Advertisement
MrStump

Random Dice Rotation Simulation

Mar 9th, 2017
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.87 KB | None | 0 0
  1. --Roll-O-Matic by MrStump
  2.  
  3. --CUSTOMIZATION VARIABLES BEGIN HERE
  4.  
  5. --Distance the dice are placed from the tool
  6. radius = 8
  7. --How high (relative to the tool) the dice are placed
  8. height = 1
  9. --How many seconds after the dice come to rest before they are auto-cleaned
  10. --If you want cleanup with no delay after roll results, use 0
  11. --A value of -1 will cause them not to be cleaned up automatically
  12. cleanupAfterRoll = 0
  13. --If the results of the roll are printed, true or false
  14. printRollResults = true
  15. --If the roll results are put into order or left as they are
  16. --Only applies to the printing of roll results, the dice are not impacted
  17. organizeRollResults = true
  18.  
  19. --END OF CUSTOMIZATION VARIABLES
  20.  
  21. function onSave()
  22.     local data_to_save = {da=diceActive, wd=watchingDice}
  23.     saved_data = JSON.encode(data_to_save)
  24.     return saved_data
  25. end
  26.  
  27. function onLoad(saved_data)
  28.     if saved_data ~= "" then
  29.         --Set up information off of loaded_data
  30.         local loaded_data = JSON.decode(saved_data)
  31.         diceActive = loaded_data.da
  32.         watchingDice = loaded_data.wd
  33.     else
  34.         diceActive = {}
  35.         watchingDice = false
  36.     end
  37.  
  38.     createButtons()
  39.     numberButtonPressed(30, "White")
  40.     rollResults = {0,0,0,0,0,0}
  41. end
  42.  
  43. --Activated by button press, pulls dice and starts process
  44. function numberButtonPressed(num, color)
  45.     if watchingDice == false then
  46.         --Delete old dice if they exist
  47.         if #diceActive > 0 then
  48.             deleteCurrentDice()
  49.         end
  50.         watchingDice = true
  51.         math.randomseed(os.time())
  52.         local bagPos, bagRot = self.getPosition(), self.getRotation()
  53.         for i=1, num do
  54.             --Create Position
  55.             local pos = getRadialPosition(i, num, bagPos, bagRot)
  56.             --Create random rotation
  57.             local rot = randomRotation()
  58.             --Removes objects from bag
  59.             applyTakeObject(pos, rot, color, num)
  60.         end
  61.     else
  62.         --Error if you try to roll dice again before the first set finishes
  63.         broadcastToColor("Dice are already being rolled.", color, {0.8,0.2,0.2})
  64.     end
  65. end
  66.  
  67. function applyTakeObject(pos, rot, color, num)
  68.     self.takeObject({
  69.         position=pos, rotation=rot,
  70.         callback="afterSpawn", callback_owner=self, params={color=color, num=num}
  71.     })
  72. end
  73.  
  74.  
  75. --Callback, runs after dice are spawned
  76. function afterSpawn(die, params)
  77.     table.insert(diceActive, die.getGUID())
  78.     if #diceActive == params.num then
  79.         self.setVar("colorForCoroutine", params.color)
  80.         startLuaCoroutine(self, "watchDice")
  81.     end
  82. end
  83.  
  84. --Coroutine, watching for all the dice to come to rest.
  85. function watchDice()
  86.     local color = self.getVar("colorForCoroutine")
  87.     local startTime = os.time()
  88.     repeat
  89.         local restingCount = 0
  90.         for i, dieGUID in ipairs(diceActive) do
  91.             local die = getObjectFromGUID(dieGUID)
  92.             if not die or die.resting == true then
  93.                 restingCount = restingCount + 1
  94.             end
  95.         end
  96.         coroutine.yield(0)
  97.     until restingCount == #diceActive or os.time() > startTime + 3
  98.     watchingDice = false
  99.     --Prints the results if printRollResults is enabled
  100.     if printRollResults == true then
  101.         formatRollResults(color)
  102.     end
  103.     --Automatically deletes the dice if cleanupAfterRoll is 0 or higher
  104.     if cleanupAfterRoll == 0 then
  105.         deleteCurrentDice()
  106.     elseif cleanupAfterRoll > 0 then
  107.         Timer.destroy("cleanupAfterRollTimer")
  108.         Timer.create({
  109.             identifier="cleanupAfterRollTimer", function_name="deleteCurrentDice",
  110.             function_owner=self, delay=cleanupAfterRoll
  111.         })
  112.     end
  113.     return 1
  114. end
  115.  
  116. --Used to delete dice from previous rolls
  117. function deleteCurrentDice()
  118.     for _, dieGUID in ipairs(diceActive) do
  119.         local die = getObjectFromGUID(dieGUID)
  120.         if die then
  121.             destroyObject(die)
  122.         end
  123.     end
  124.     diceActive = {}
  125.     watchingDice = false
  126.     numberButtonPressed(30, "White")
  127. end
  128.  
  129. --Obtains values for rolls and orders them
  130. function formatRollResults(color)
  131.     for _, dieGUID in ipairs(diceActive) do
  132.         local die = getObjectFromGUID(dieGUID)
  133.         if die then
  134.             local value = die.getValue()
  135.             rollResults[value] = rollResults[value] + 1
  136.         end
  137.     end
  138.     print("One: "..rollResults[1])
  139.     print("Two: "..rollResults[2])
  140.     print("Three: "..rollResults[3])
  141.     print("Four: "..rollResults[4])
  142.     print("Five: "..rollResults[5])
  143.     print("Six: "..rollResults[6])
  144.     print("-----------------")
  145.  
  146. end
  147.  
  148. --Get a radial position to place item
  149. function getRadialPosition(i, i_max, pos, rot)
  150.     local spokes = 360/i_max
  151.     local posX = pos.x + math.sin( math.rad((spokes*i)+rot.y) ) * radius
  152.     local posY = pos.y + height
  153.     local posZ = pos.z + math.cos( math.rad((spokes*i)+rot.y) ) * radius
  154.     return {x=posX, y=posY, z=posZ}
  155. end
  156.  
  157. --Gets a random rotation vector
  158. function randomRotation()
  159.     --Credit for this function goes to Revinor (forums)
  160.     --Get 3 random numbers
  161.     local u1 = math.random();
  162.     local u2 = math.random();
  163.     local u3 = math.random();
  164.     --Convert them into quats to avoid gimbal lock
  165.     local u1sqrt = math.sqrt(u1);
  166.     local u1m1sqrt = math.sqrt(1-u1);
  167.     local qx = u1m1sqrt *math.sin(2*math.pi*u2);
  168.     local qy = u1m1sqrt *math.cos(2*math.pi*u2);
  169.     local qz = u1sqrt *math.sin(2*math.pi*u3);
  170.     local qw = u1sqrt *math.cos(2*math.pi*u3);
  171.     --Apply rotation
  172.     local ysqr = qy * qy;
  173.     local t0 = -2.0 * (ysqr + qz * qz) + 1.0;
  174.     local t1 = 2.0 * (qx * qy - qw * qz);
  175.     local t2 = -2.0 * (qx * qz + qw * qy);
  176.     local t3 = 2.0 * (qy * qz - qw * qx);
  177.     local t4 = -2.0 * (qx * qx + ysqr) + 1.0;
  178.     --Correct
  179.     if t2 > 1.0 then t2 = 1.0 end
  180.     if t2 < -1.0 then ts = -1.0 end
  181.     --Convert back to X/Y/Z
  182.     local xr = math.asin(t2);
  183.     local yr = math.atan2(t3, t4);
  184.     local zr = math.atan2(t1, t0);
  185.     --Return result
  186.     return {math.deg(xr),math.deg(yr),math.deg(zr)}
  187. end
  188.  
  189. --Button creation
  190. function createButtons()
  191.     --Spawns number buttons and assigns a function trigger for each
  192.     for i, pos in ipairs(buttonPositionList) do
  193.         self.createButton({
  194.             click_function="but"..i, function_owner=self,
  195.             position=pos, height=150, width=150
  196.         })
  197.         local func = function(_,color) numberButtonPressed(i, color) end
  198.         self.setVar("but"..i, func)
  199.     end
  200.  
  201.     --Spawns deleteCurrentDice button
  202.     self.createButton({
  203.         click_function="deleteCurrentDice", function_owner=self,
  204.         position={0,0,0.73}, height=150, width=150
  205.     })
  206. end
  207.  
  208. --Data table of positions for number buttons 1-9, in order
  209. buttonPositionList = {
  210.     {-0.435,0,0.59}, {-0.693,0,0.22}, {-0.693,0,-0.22}, {-0.435,0,-0.59},
  211.     {0,0,-0.73}, {0.435,0,-0.59}, {0.693,0,-0.22}, {0.693,0,0.22}, {0.435,0,0.59}
  212. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement