Novaknight

dice box

Sep 23rd, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.19 KB | None | 0 0
  1. --Based off: https://steamcommunity.com/sharedfiles/filedetails/?id=726800282
  2. --Link for this mod: https://steamcommunity.com/sharedfiles/filedetails/?id=959360907
  3.  
  4. --Initialize Global Variables and pRNG Seed
  5. math.randomseed(tonumber(tostring(os.time()):reverse():sub(1,7))+tonumber(tostring(os.clock()):reverse():sub(1,7)))
  6. ver = 'BCB-2018-05-13'
  7. lastHolder = {}
  8. customFace = {4, 6, 8, 10, 12, 20}
  9. diceGuidFaces = {}
  10. sortedKeys = {}
  11. resultsTable = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  12.  
  13. --Determine the person who put the dice in the box.
  14. function onObjectPickedUp(playerColor, obj)
  15. lastHolder[obj] = playerColor
  16. end
  17.  
  18. --Reset the person holding the dice when no dice are held.
  19. function onObjectDestroyed(obj)
  20. lastHolder[obj] = nil
  21. end
  22.  
  23. --Reset description on load if empty.
  24. function onLoad(save_state)
  25. if self.getDescription() == '' then
  26. setDefaultState()
  27. end
  28. end
  29.  
  30. --Returns description on game save.
  31. function onSave()
  32. return self.getDescription()
  33. end
  34.  
  35. --Reset description on drop if empty.
  36. function onDropped(player_color)
  37. if self.getDescription() == '' then
  38. setDefaultState()
  39. end
  40. end
  41.  
  42. --Sets default description.
  43. function setDefaultState()
  44. self.setDescription(JSON.encode_pretty({Results = 'no', SmoothDice = 'no', Rows = 'yes', SortNoRows = 'asc', Step = 1, Version = ver}))
  45. end
  46.  
  47. --Creates a table and sorts the dice guids by value.
  48. function sortByVal(t, type)
  49. local keys = {}
  50. for key in pairs(t) do
  51. table.insert(keys, key)
  52. end
  53. if type == 'asc' then
  54. table.sort(keys, function(a, b) return t[a] < t[b] end)
  55. elseif type == 'desc' then
  56. table.sort(keys, function(a, b) return t[a] > t[b] end)
  57. end
  58. return keys
  59. end
  60.  
  61. --Checks the item dropped in the bag has a guid.
  62. function hasGuid(t, g)
  63. for k, v in ipairs(t) do
  64. if v.guid == g then return true end
  65. end
  66.  
  67. return false
  68. end
  69.  
  70. --Runs when an object is dropped in bag.
  71. function onCollisionEnter(collision_info)
  72. playerColor = lastHolder[collision_info.collision_object]
  73. if collision_info.collision_object.getGUID() == nil then return end
  74. diceGuidFaces = {}
  75. sortedKeys = {}
  76.  
  77. --Save number of faces on dice
  78. for k, v in ipairs(getAllObjects()) do
  79. if v.tag == 'Dice' then
  80. objType = tostring(v)
  81. faces = tonumber(string.match(objType, 'Die_(%d+).*'))
  82. if faces == nil then
  83. faces = tonumber(customFace[v.getCustomObject().type + 1])
  84. end
  85. diceGuidFaces[v.getGUID()] = faces
  86. table.insert(sortedKeys, v.getGUID())
  87. end
  88. end
  89.  
  90. --[[Benchmarking code
  91. if resetclock ~= 1 then
  92. clockstart = os.clock()
  93. resetclock = 1
  94. end--]]
  95.  
  96. --Destroys any lingering timers
  97. Timer.destroy('takeDiceOut' .. self.getGUID())
  98.  
  99. --Creates a timer to take the dice out and position them.
  100. Timer.create({identifier = 'takeDiceOut' .. self.getGUID(), function_name = 'takeDiceOut', function_owner = self, parameters = {}, delay = 0.3, repetitions = 1})
  101. end
  102.  
  103. --Function to take the dice out of the bag and position them.
  104. function takeDiceOut(tab)
  105. local data = JSON.decode(self.getDescription())
  106. if data == nil then
  107. setDefaultState()
  108. data = JSON.decode(self.getDescription())
  109. printToAll('Warning - invalid description. Restored default configuration.', {0.8, 0.5, 0})
  110. end
  111.  
  112. if data.Step < 1 then
  113. setDefaultState()
  114. data = JSON.decode(self.getDescription())
  115. printToAll('Warning - "step" can\'t be lower than 1. Restored default configuration.', {0.8, 0.5, 0})
  116. end
  117.  
  118. diceGuids = {}
  119. for k, v in pairs(self.getObjects()) do
  120. faces = diceGuidFaces[v.guid]
  121. r = math.random(faces)
  122. diceGuids[v.guid] = r
  123. end
  124.  
  125. local objs = self.getObjects()
  126. local position = self.getPosition()
  127. rotation = self.getRotation()
  128. sortedKeys = sortByVal(diceGuids, data.SortNoRows)
  129. Rows = {}
  130. n = 1
  131. for _, key in pairs(sortedKeys) do
  132. if diceGuids[key] == math.floor(diceGuids[key]) then
  133. resultsTable[diceGuids[key]] = resultsTable[diceGuids[key]] + 1
  134. end
  135.  
  136. if hasGuid(objs, key) then
  137. if Rows[diceGuids[key]] == nil then
  138. Rows[diceGuids[key]] = 0
  139. end
  140. Rows[diceGuids[key]] = Rows[diceGuids[key]] + 1
  141. params = {}
  142. params.guid = key
  143. if data.Rows == 'no' then
  144. params.position = { position.x + (-1) * math.sin((90 + rotation.y) * 0.0174532) * (n + 0.5) * data.Step,
  145. position.y + 1,
  146. position.z + (-1) * math.cos((90 + rotation.y) * 0.0174532) * (n + 0.5) * data.Step}
  147. else
  148. params.position = {
  149. position.x + (Rows[diceGuids[key]] * math.cos((180 + self.getRotation().y) * 0.0174532)) * data.Step - (diceGuids[key] * math.sin((180 + self.getRotation().y) * 0.0174532)) * data.Step,
  150. position.y + 2,
  151. position.z + (Rows[diceGuids[key]] * math.sin((self.getRotation().y) * 0.0174532)) * data.Step + (diceGuids[key] * math.cos((0 + self.getRotation().y) * 0.0174532)) * data.Step}
  152. end
  153.  
  154. --params.rotation = {rotation.x, rotation.y, rotation.z}
  155. params.callback = 'setValueCallback'
  156. params.params = {diceGuids[key]}
  157. params.smooth = false
  158. if data.SmoothDice == 'yes' then params.smooth = true end
  159. self.takeObject(params)
  160. n = n + 1
  161. end
  162. end
  163.  
  164. printresultsTable()
  165. --[[Benchmarking code
  166. clockend = os.clock()
  167. resetclock=0
  168. print('Runtime: ' .. clockend-clockstart .. ' seconds.')--]]
  169. end
  170.  
  171. --Function to count resultsTable for printing.
  172. function sum(t)
  173. local sum = 0
  174. for k, v in pairs(t) do
  175. sum = sum + v
  176. end
  177.  
  178. return sum
  179. end
  180.  
  181. --Prints resultsTable.
  182. function printresultsTable()
  183. local data = JSON.decode(self.getDescription())
  184. if sum(resultsTable) > 0 and data.Results == 'yes' then
  185. local description = {'Ones.', 'Twos.', 'Threes.', 'Fours.', 'Fives.', 'Sixes.', 'Sevens.', 'Eights.', 'Nines.', 'Tens.', 'Elevens.', 'Twelves.', 'Thirteens.', 'Fourteens.', 'Fifteens.', 'Sixteens.', 'Seventeens', 'Eighteens.', 'Nineteens.', 'Twenties.'}
  186. local msg = ''
  187. for dieFace, numRolled in ipairs(resultsTable) do
  188. if numRolled > 0 then
  189. msg = msg .. numRolled .. ' ' .. description[dieFace] .. ' '
  190. end
  191. end
  192.  
  193. local time = '[' .. os.date("%H") .. ':' .. os.date("%M") .. ':' .. os.date("%S") .. ' UTC] '
  194. if playerColor == nil then
  195. printToAll('*******************************************************\n' .. time .. '~UNKNOWN PLAYER~ rolls:\n' .. msg .. '*******************************************************', {1, 1, 1})
  196. else
  197. printToAll('*******************************************************\n' .. time .. Player[playerColor].steam_name .. ' rolls:\n' .. msg .. '*******************************************************', stringColorToRGB(playerColor))
  198. end
  199. end
  200.  
  201. for k,v in ipairs(resultsTable) do
  202. resultsTable[k] = 0
  203. end
  204. end
  205.  
  206. --Sets the value of the physical dice object and reorients them if needed.
  207. function setValueCallback(obj, tab)
  208. local isSquare = false
  209. if (rotation.y < 2) or (88 < rotation.y and rotation.y < 92) or (178 < rotation.y and rotation.y < 182) or (268 < rotation.y and rotation.y < 272) or (rotation.y > 358) then isSquare = true end
  210. function insidef()
  211. obj.setValue(tab[1])
  212. local isThisABloodyCustomDie = obj.getCustomObject()
  213. local reorientAllDice = false
  214. if obj.tag == 'Dice' then
  215. objType = tostring(obj)
  216. callFaces = tonumber(string.match(objType, 'Die_(%d+).*'))
  217. if callFaces == nil then callFaces = tonumber(customFace[obj.getCustomObject().type + 1]) end
  218. diceGuidFaces[obj.getGUID()] = callFaces
  219. end
  220.  
  221. if isSquare then
  222. if isThisABloodyCustomDie.image ~= nil and callFaces == 6 then
  223. waitFrames(35)
  224. local rot = self.getRotation()
  225. local r = obj.getRotation()
  226. obj.setRotation({r.x, rot.y + 180, r.z})
  227. end
  228. else
  229. if callFaces == 6 then
  230. waitFrames(35)
  231. local rot = self.getRotation()
  232. local r = obj.getRotation()
  233. obj.setRotation({r.x, rot.y + 180, r.z})
  234. end
  235. end
  236.  
  237. return 1
  238. end
  239.  
  240. startLuaCoroutine(self, 'insidef')
  241. end
  242.  
  243. --Coroutine to wait to allow for custom dice positional data to be altered.
  244. function waitFrames(frames)
  245. while frames > 0 do
  246. coroutine.yield(0)
  247. frames = frames - 1
  248. end
  249. end
  250.  
  251. --Destroys lingering timers when the bag is destroyed.
  252. function onDestroy()
  253. Timer.destroy('takeDiceOut' .. self.getGUID())
  254. end
  255.  
  256. --Function to print table contents.
  257. --[[
  258. function printTable(tempTable)
  259. for k, v in pairs(tempTable) do
  260. print('key = ' .. k)
  261. print('value =' .. v)
  262. end
  263. end
  264. --]]
Advertisement
Add Comment
Please, Sign In to add comment