· 9 years ago · Dec 27, 2016, 08:56 PM
1--[[Global variables--]]
2
3--[[ Customizable variables --]]
4
5convertfailcountlimit = 50 -- when bets are converted to pot, the number of failed attempts allowed before it falls back to move bets (each attempt takes two frames)
6options = {
7
8 ["dealdelay1"] = 0.1, -- delay (in seconds) used when dealing players their hands
9 ["dealdelay2"] = 0.4, -- delay (in seconds) used when dealing community cards
10 ["blindsskipafk"] = false, -- If false, afk players still pay blinds when it's their time. Change to true if you want blinds to skip afk players.
11 ["actiontoggle"] = true, -- toggle whether the game displays actiontext. set this to false if you want to have it off by default
12 ["playerclickaction"] = true, -- toggle whether action button stays in place (false) or moves from player to player (true)
13 ["gamemode"] = 'texas', -- Game mode (currently supports Texas Hold'em ('texas'), Pineapple ('pineapple'), and Omaha Hold'em ('omaha'))
14 ["collectmethod"] = 'move', -- method used by collect bets. options: 'move': moves bets; 'convert': converts bets up, 'hybrid': starts with move, changes to convert when pot>hybridthreshold
15 ["hybridthreshold"] = 10000, -- used with hybrid collection, the point above which collection switches from move to convert
16 ["enforcedoubleraise"] = true, -- if true, does not let a player pass action if their raise is less than double the current bet and they are not all in.
17 ["enforcepotlimit"] = false, -- if true, does not let a player pass action if they bet too much for pot limit. the bet limit is calculated as: pot + currentbet + (currentbet - action player's bet)
18 ["enforcedfoldinturn"] = false, -- if true, players may not use the fold hand buttons to fold out of turn
19 ["clocktime"] = 30,
20 ["autoclock"] = false,
21 ["autofold"] = false,
22 ["autoclocktime"] = 10,
23 ["clockpausebutton"] = false,
24 ["chatoptions"] =
25 {
26 ["actionmessage"] = true, -- print "Action on player" message in chat
27 ["actionbroadcast"] = true, -- broadcast "Action on you!" to the current player
28 ["currentbetmessage"] = true, -- broadcast when the current bet changes
29 ["better"] = true, -- include the player who made or raised in the above message
30 ["potmessage"] = 2, -- 0 = never, 1 = on collect bets only, 2 = any time it changes as well as on collection
31 ["allinbroadcast"] = true, -- broadcast when a player is all in
32 ["stage"] = true -- flop, turn, river broadcasts
33 }
34
35}
36
37--[[ Other variables and tables --]]
38onecard = false -- used when dealing one card from options menu (for determining starting dealer, etc)
39handinprogress = false -- used to prevent changing of gamemode during a hand
40convertfailcount = 0
41holedealt = false -- whether or not players have been dealt their hole cards
42dealing = false -- set to true while cards are being dealt to prevent double-clicking
43players = {} -- table of seated players used for dealing cards and actions
44actionon = nil -- Player whose turn it is to act
45playerbets = {} -- Table of players' bets
46currentbet = 0 -- highest bet from the playerbets table
47mainpotchips = {} -- table containing information regarding stacks of chips in the main pot(initialized in initializePot() function)
48printstring = '' -- string referenced by printMessages function to know which messages to print.
49pot = 0 -- total amount in pot (including current players' bets)
50themeindex = 1
51subthemeindex = 1
52
53--[[ Object references and GUIDs --]]
54actionbutton = {}
55actionbuttonGUID = 'b34d88'
56betzones = {} -- scripting zones for the betting areas for each player. Order must correspond to colors table
57betzoneGUIDs = {'420cfb', '39fd59', '7d419f', '332aa4', '0377d5', '8a2729', 'db2d03', 'b93bb7', 'c43aea', '3a8997'}
58boardobject = {} -- 3d model used for the board
59boardobjectGUID = '48721b'
60boardzone = {} -- scripting zone on the board where community cards are dealt
61boardzoneGUID = '5a1d5c'
62collectbutton = {} -- button to collect bets
63collectbuttonGUID = 'e801e4'
64clock = null
65dealbutton = {} -- button to deal cards
66dealbuttonGUID = '1745d7'
67deck = {} -- deck
68deckGUID = 'aef879' -- the deck's GUID which is saved on the table
69muck = {} -- the muck object that is used to determine where burn cards are dealt
70muckGUID = 'be42ca'
71newdeckbutton = {} -- button to spawn a new deck
72newdeckbuttonGUID = 'ea1c95'
73potobject = {}
74potobjectGUID = '6a79c6'
75resetbutton = {} -- button to reset the game
76resetbuttonGUID = 'c3b0f3'
77tablezones = {}
78tablezoneGUIDs = {'fe7624', 'b8cde0', 'f33c02', 'a96804', '08e7a3', 'e2ff95', '92c6c4', 'd03a42', 'd1cf88', '71d958'}
79
80colors = {"White", "Brown", "Red", "Orange", "Yellow", "Green", "Teal", "Blue", "Purple", "Pink"} --list of all colors, in order
81fontcolors = {}
82
83 for i, v in ipairs (colors) do
84 fontcolors[v] = {}
85 end
86
87 fontcolors.White.r = 1
88 fontcolors.White.g = 1
89 fontcolors.White.b = 1
90 fontcolors.White.bbcode = '[ffffff]'
91
92 fontcolors.Brown.r = 0.443
93 fontcolors.Brown.g = 0.231
94 fontcolors.Brown.b = 0.09
95 fontcolors.Brown.bbcode = '[713b17]'
96
97 fontcolors.Red.r = 0.856
98 fontcolors.Red.g = 0.1
99 fontcolors.Red.b = 0.094
100 fontcolors.Red.bbcode = '[da1918]'
101
102 fontcolors.Orange.r = 0.956
103 fontcolors.Orange.g = 0.392
104 fontcolors.Orange.b = 0.113
105 fontcolors.Orange.bbcode = '[f4641d]'
106
107 fontcolors.Yellow.r = 0.905
108 fontcolors.Yellow.g = 0.898
109 fontcolors.Yellow.b = 0.172
110 fontcolors.Yellow.bbcode = '[e7e52c]'
111
112 fontcolors.Green.r = 0.192
113 fontcolors.Green.g = 0.701
114 fontcolors.Green.b = 0.168
115 fontcolors.Green.bbcode = '[31b32b]'
116
117 fontcolors.Teal.r = 0.129
118 fontcolors.Teal.g = 0.694
119 fontcolors.Teal.b = 0.607
120 fontcolors.Teal.bbcode = '[21b19b]'
121
122 fontcolors.Blue.r = 0.118
123 fontcolors.Blue.g = 0.53
124 fontcolors.Blue.b = 1
125 fontcolors.Blue.bbcode = '[1f87ff]'
126
127 fontcolors.Purple.r = 0.627
128 fontcolors.Purple.g = 0.125
129 fontcolors.Purple.b = 0.941
130 fontcolors.Purple.bbcode = '[a020f0]'
131
132 fontcolors.Pink.r = 0.96
133 fontcolors.Pink.g = 0.439
134 fontcolors.Pink.b = 0.807
135 fontcolors.Pink.bbcode = '[f570ce]'
136
137potzones = {}
138mainpotzoneGUID = 'a20d35'
139pottext = {}
140pottextGUID = 'a5130f'
141mainpottext = {}
142mainpottextGUID = '476499'
143currenbettext = {}
144currentbettextGUID = 'ed7b0b'
145colorball = null
146overlay = {}
147overlayGUID = '290051'
148actiontext = {}
149actiontextGUID = '20e11d'
150optionspanel = nil
151optionsbutton = {}
152optionsbuttonGUID = '6e1caf'
153scripts = {} -- Scripts copied from objects in onload, used when 'Reset Objects' is clicked.
154
155--[[ Overlay images --]]
156themes =
157{
158 { -- themeindex 1
159 ["label"] = 'Anime',
160 { -- subthemeindex 1
161 ["label"] = 'Normieshit1',
162 { -- 1
163 ["label"] = 'Cowboy Bebop',
164 ["diffuse"] = 'http://i.imgur.com/VyfS447.jpg'
165 },
166 { -- 2
167 ["label"] = 'Cowboy Bebop cards',
168 ["diffuse"] = 'http://i.imgur.com/lOQOdky.jpg'
169 },
170 { -- 3
171 ["label"] = 'Cowboy Bebop bang hand',
172 ["diffuse"] = 'http://i.imgur.com/S8IiygG.jpg'
173 }
174 },
175 { -- subthemeindex 2
176 ["label"] = 'Hidamari Sketch',
177 { -- 1
178 ["label"] = 'Swimsuits',
179 ["diffuse"] = 'http://i.imgur.com/pL1qEHD.jpg'
180 },
181 { -- 2
182 ["label"] = 'Yunocchi',
183 ["diffuse"] = 'http://i.imgur.com/c0y8yiu.jpg'
184 },
185 { -- 3
186 ["label"] = 'Yuno (wide)',
187 ["diffuse"] = 'http://i.imgur.com/okv9OWS.jpg'
188 }
189 },
190 { -- subthemeindex 3
191 ["label"] = 'GochiUsa 1',
192 { -- 1
193 ["label"] = 'Group 1',
194 ["diffuse"] = 'http://i.imgur.com/dUPOwBT.jpg'
195 },
196 { -- 2
197 ["label"] = 'Group 2',
198 ["diffuse"] = 'http://i.imgur.com/dlqVrVH.jpg'
199 },
200 { -- 3
201 ["label"] = 'Group Casino',
202 ["diffuse"] = 'http://i.imgur.com/yvrQqJs.jpg'
203 },
204 { -- 4
205 ["label"] = 'Group Underwater',
206 ["diffuse"] = 'http://i.imgur.com/bLcKafe.jpg'
207 },
208 { -- 5
209 ["label"] = 'Group Christmas',
210 ["diffuse"] = 'http://i.imgur.com/OaU0e9w.jpg'
211 },
212 { -- 6
213 ["label"] = 'ChiMaMe',
214 ["diffuse"] = 'http://i.imgur.com/HZPKtIC.jpg'
215 },
216 { -- 7
217 ["label"] = 'Chino Rize Syaro Idols',
218 ["diffuse"] = 'http://i.imgur.com/t3isOTZ.jpg'
219 },
220 { -- 8
221 ["label"] = 'Cocoa Chino Rize',
222 ["diffuse"] = 'http://i.imgur.com/o5XmWaK.jpg'
223 },
224 { -- 9
225 ["label"] = 'Cocoa Chino',
226 ["diffuse"] = 'http://i.imgur.com/kTYlDbp.jpg'
227 },
228 { -- 10
229 ["label"] = 'Chino Chiya',
230 ["diffuse"] = 'http://i.imgur.com/YwaTHgK.jpg'
231 }
232 },
233 { -- subthemeindex 4
234 ["label"] = 'GochiUsa 2',
235 { -- 1
236 ["label"] = 'Chino Cards',
237 ["diffuse"] = 'http://i.imgur.com/rkarO8n.jpg'
238 },
239 { -- 2
240 ["label"] = 'Chino in Wonderland',
241 ["diffuse"] = 'http://i.imgur.com/K0P0wVC.jpg'
242 },
243 { -- 3
244 ["label"] = 'Chino Smile',
245 ["diffuse"] = 'http://i.imgur.com/rQm3RCZ.jpg'
246 },
247 { -- 4
248 ["label"] = 'Chino in Bed',
249 ["diffuse"] = 'http://i.imgur.com/qLSSbEn.jpg'
250 }
251 },
252 { -- subthemeindex 5
253 ["label"] = 'Madoka Magica 1',
254 { -- 1
255 ["label"] = 'Group',
256 ["diffuse"] = 'http://i.imgur.com/mxSr46k.jpg'
257 },
258 { -- 2
259 ["label"] = 'Group on grass',
260 ["diffuse"] = 'http://i.imgur.com/vQN3GGv.jpg'
261 },
262 { -- 3
263 ["label"] = 'Mexican standoff',
264 ["diffuse"] = 'http://i.imgur.com/WcYTwzo.jpg'
265 },
266 { -- 4
267 ["label"] = 'Group stained glass',
268 ["diffuse"] = 'http://i.imgur.com/BT0JHRa.jpg'
269 },
270 { -- 5
271 ["label"] = 'Madoka gangsta',
272 ["diffuse"] = 'http://i.imgur.com/ScepCXj.jpg'
273 },
274 { -- 6
275 ["label"] = 'Madoka in water',
276 ["diffuse"] = 'http://i.imgur.com/MQtkTUy.jpg'
277 },
278 { -- 7
279 ["label"] = 'Ultimate Madoka',
280 ["diffuse"] = 'http://i.imgur.com/DfqMJRt.jpg'
281 },
282 { -- 8
283 ["label"] = 'Ultimate Madoka 2',
284 ["diffuse"] = 'http://i.imgur.com/yoqS5Zy.jpg'
285 },
286 { -- 9
287 ["label"] = 'Sayaka',
288 ["diffuse"] = 'http://i.imgur.com/KvVb3Gt.jpg'
289 },
290 { -- 10
291 ["label"] = 'Sayaka on bed (pantsu)',
292 ["diffuse"] = 'http://i.imgur.com/ZJUCoFw.jpg'
293 }
294 },
295 { -- subthemeindex 6
296 ["label"] = 'Madoka Magica 2',
297 { -- 1
298 ["label"] = 'Homura',
299 ["diffuse"] = 'http://i.imgur.com/9HE2oYu.jpg'
300 },
301 { -- 2
302 ["label"] = 'Mami fishing Charlotte',
303 ["diffuse"] = 'http://i.imgur.com/F1JKHfc.jpg'
304 },
305 { -- 3
306 ["label"] = 'Mami vs witches',
307 ["diffuse"] = 'http://i.imgur.com/Oen3IgK.jpg'
308 },
309 { -- 4
310 ["label"] = 'Kyouko',
311 ["diffuse"] = 'http://i.imgur.com/B082C3C.jpg'
312 },
313 { -- 5
314 ["label"] = 'Kyouko2 (pantsu)',
315 ["diffuse"] = 'http://i.imgur.com/cFZKGMA.jpg'
316 },
317 { -- 6
318 ["label"] = 'KyouSaya',
319 ["diffuse"] = 'http://i.imgur.com/9LB82tZ.jpg'
320 },
321 { -- 7
322 ["label"] = 'QB gonna get raped',
323 ["diffuse"] = 'http://i.imgur.com/mtsP5cp.jpg'
324 }
325 },
326 { -- subthemeindex 7
327 ["label"] = 'Yuru Yuri 1',
328 { -- 1
329 ["label"] = 'Akari Collage',
330 ["diffuse"] = 'http://i.imgur.com/DS4pCpQ.jpg'
331 },
332 { -- 2
333 ["label"] = 'Akaris 1',
334 ["diffuse"] = 'http://i.imgur.com/xA8YRLg.jpg'
335 },
336 { -- 3
337 ["label"] = 'Akaris 2',
338 ["diffuse"] = 'http://i.imgur.com/YqNCXSG.jpg'
339 },
340 { -- 4
341 ["label"] = 'アッカリーン',
342 ["diffuse"] = 'http://i.imgur.com/o003PFP.jpg'
343 },
344 { -- 5
345 ["label"] = 'Kyouko Collage',
346 ["diffuse"] = 'http://i.imgur.com/lauT9ym.jpg'
347 },
348 { -- 6
349 ["label"] = 'Kyoukos 1',
350 ["diffuse"] = 'http://i.imgur.com/CtMp0K4.jpg'
351 },
352 { -- 7
353 ["label"] = 'Kyoukos 2',
354 ["diffuse"] = 'http://i.imgur.com/81KhU3Z.jpg'
355 },
356 { -- 8
357 ["label"] = 'Yui Collage',
358 ["diffuse"] = 'http://i.imgur.com/cwLhHDr.jpg'
359 },
360 { -- 9
361 ["label"] = 'Yuis',
362 ["diffuse"] = 'http://i.imgur.com/F1P0fP5.jpg'
363 }
364 },
365 { -- subthemeindex 8
366 ["label"] = 'Yuru Yuri 2',
367 { -- 1
368 ["label"] = 'Chinatsu Collage',
369 ["diffuse"] = 'http://i.imgur.com/h4yJ539.jpg'
370 },
371 { -- 2
372 ["label"] = 'Chinatsus',
373 ["diffuse"] = 'http://i.imgur.com/PCyMWCQ.jpg'
374 },
375 { -- 3
376 ["label"] = 'Rise',
377 ["diffuse"] = 'http://i.imgur.com/riSmzZl.jpg'
378 },
379 { -- 4
380 ["label"] = 'Pajama Party 1',
381 ["diffuse"] = 'http://i.imgur.com/MQp58p5.jpg'
382 },
383 { -- 5
384 ["label"] = 'Pajama Party 2',
385 ["diffuse"] = 'http://i.imgur.com/chHWsfG.jpg'
386 },
387 { -- 6
388 ["label"] = 'Gorakubu 1',
389 ["diffuse"] = 'http://i.imgur.com/3Hhw09L.jpg'
390 },
391 { -- 7
392 ["label"] = 'Gorakubu 2',
393 ["diffuse"] = 'http://i.imgur.com/cgQz7pf.jpg'
394 },
395 { -- 8
396 ["label"] = 'Gorakubu 3',
397 ["diffuse"] = 'http://i.imgur.com/ZG2iorU.jpg'
398 },
399 { -- 9
400 ["label"] = 'Gorakubu Idols',
401 ["diffuse"] = 'http://i.imgur.com/EX8t7ke.jpg'
402 },
403 { -- 10
404 ["label"] = 'Gorakubu Swimming',
405 ["diffuse"] = 'http://i.imgur.com/XzItDAk.jpg'
406 }
407 },
408 { -- subthemeindex 9
409 ["label"] = 'Yuru Yuri 3',
410 { -- 1
411 ["label"] = 'Gorakubu Picnic',
412 ["diffuse"] = 'http://i.imgur.com/4Z5PpXX.jpg'
413 },
414 { -- 2
415 ["label"] = 'Gorakubu Halloween',
416 ["diffuse"] = 'http://i.imgur.com/xs6D7cm.jpg'
417 },
418 { -- 3
419 ["label"] = 'Seitokai',
420 ["diffuse"] = 'http://i.imgur.com/9FhXJdz.jpg'
421 },
422 { -- 4
423 ["label"] = 'First Years',
424 ["diffuse"] = 'http://i.imgur.com/aLyyGqd.jpg'
425 },
426 { -- 5
427 ["label"] = 'Second Years',
428 ["diffuse"] = 'http://i.imgur.com/8YYChdB.jpg'
429 },
430 { -- 6
431 ["label"] = 'SakuHima 1',
432 ["diffuse"] = 'http://i.imgur.com/IvpYMVF.jpg'
433 },
434 { -- 7
435 ["label"] = 'SakuHima Bunnies',
436 ["diffuse"] = 'http://i.imgur.com/Uxige1K.jpg'
437 },
438 { -- 8
439 ["label"] = 'SakuHima Christmas',
440 ["diffuse"] = 'http://i.imgur.com/kJugXPJ.jpg'
441 },
442 { -- 9
443 ["label"] = 'Chinatsu x Kyouko',
444 ["diffuse"] = 'http://i.imgur.com/0QfKfUq.jpg'
445 },
446 { -- 10
447 ["label"] = 'Kyouko x Ayano',
448 ["diffuse"] = 'http://i.imgur.com/OXkcHV6.jpg'
449 }
450 },
451 { --subthemeindex 10
452 ["label"] = 'Misc/Crossover',
453 { -- 1
454 ["label"] = 'They see your short stack',
455 ["diffuse"] = 'http://i.imgur.com/64Eorc2.jpg'
456 },
457 { -- 2
458 ["label"] = 'Loli space parade',
459 ["diffuse"] = 'http://i.imgur.com/tOzcNeE.jpg'
460 },
461 { -- 3
462 ["label"] = 'GochiUsa x KinMoza',
463 ["diffuse"] = 'http://i.imgur.com/LsqaE1C.jpg'
464 }
465 }
466 },
467 { -- themeindex 2
468 ["label"] = 'Games',
469 { -- subthemeindex 1
470 ["label"] = 'Portal',
471 { -- 1
472 ["label"] = 'Aperture Labs',
473 ["diffuse"] = 'http://i.imgur.com/EBM4HqE.jpg'
474 },
475 { -- 2
476 ["label"] = 'Falling into portal',
477 ["diffuse"] = 'http://i.imgur.com/V07Jfam.jpg'
478 }
479 }
480 },
481 { -- themeindex 3
482 ["label"] = 'Other',
483 { -- subthemeindex 1
484 ["label"] = 'Music',
485 {
486 ["label"] = 'Sheet Music',
487 ["diffuse"] = 'http://i.imgur.com/WsiBbTY.jpg'
488 },
489 {
490 ["label"] = 'Violin',
491 ["diffuse"] = 'http://i.imgur.com/NTkgsv5.jpg'
492 }
493 },
494 { -- subthemeindex 2
495 ["label"] = 'Nature',
496 {
497 ["label"] = 'Milky Way Sky',
498 ["diffuse"] = 'http://i.imgur.com/j8ZofIk.jpg'
499 },
500 {
501 ["label"] = 'Andromeda Galaxy',
502 ["diffuse"] = 'http://i.imgur.com/DiOrDTl.jpg'
503 },
504 {
505 ["label"] = 'Ocean Water',
506 ["diffuse"] = 'http://i.imgur.com/mqQhZDb.jpg'
507 },
508 {
509 ["label"] = 'Coral Reef',
510 ["diffuse"] = 'http://i.imgur.com/6uWY2PN.jpg'
511 }
512 },
513 { -- subthemeindex 3
514 ["label"] = 'Poker',
515 {
516 ["label"] = 'Plain Felt',
517 ["diffuse"] = 'http://i.imgur.com/jPnTE9e.png'
518 },
519 {
520 ["label"] = 'Suits Pattern',
521 ["diffuse"] = 'http://i.imgur.com/tzJiYRn.png'
522 }
523 }
524 }
525}
526
527--[[ onLoad function --]]
528
529function onload (save_state)
530
531 local saveddata = JSON.decode(save_state)
532
533 --[[ Get object references --]]
534 boardzone = getObjectFromGUID(boardzoneGUID)
535 newdeckbutton = getObjectFromGUID(newdeckbuttonGUID)
536 dealbutton = getObjectFromGUID(dealbuttonGUID)
537 resetbutton = getObjectFromGUID(resetbuttonGUID)
538 muckzone = getObjectFromGUID(muckzoneGUID)
539 collectbutton = getObjectFromGUID(collectbuttonGUID)
540 for i, v in ipairs (colors) do
541 betzones[v] = getObjectFromGUID(betzoneGUIDs[i])
542 tablezones[v] = getObjectFromGUID(tablezoneGUIDs[i])
543 end
544 pottext = getObjectFromGUID(pottextGUID)
545 potzones[1] = getObjectFromGUID(mainpotzoneGUID)
546 actiontext = getObjectFromGUID(actiontextGUID)
547 actionbutton = getObjectFromGUID(actionbuttonGUID)
548 currentbettext = getObjectFromGUID(currentbettextGUID)
549 optionsbutton = getObjectFromGUID(optionsbuttonGUID)
550
551 if saveddata == nil then
552 --[[ Initialize texts --]]
553 hideActionText()
554 pottext.setPosition ({0, 1.33, 0})
555 pottext.setRotation ({90, 180, 0})
556 currentbettext.setPosition ({0, 1.33, 1})
557 currentbettext.setRotation({90, 180, 0})
558
559 mainpotchips = initializePot()
560 else
561 if saveddata.options ~= nil then options = saveddata.options end
562
563 holedealt = saveddata.holedealt
564 dealing = saveddata.dealing
565 players = saveddata.players
566 actionon = saveddata.actionon
567 playerbets = saveddata.playerbets
568 currentbet = saveddata.currentbet
569 mainpotchips = saveddata.mainpotchips
570 pot = saveddata.pot
571 collecting = saveddata.collecting
572 collectmethod = saveddata.collectmethod
573 hybridthreshold = saveddata.hybridthreshold
574 handinprogress = saveddata.handinprogress
575
576 deckGUID = saveddata.deckGUID
577 muckGUID = saveddata.muckGUID
578 potobjectGUID = saveddata.potobjectGUID
579 boardobjectGUID = saveddata.boardobjectGUID
580 overlayGUID = saveddata.overlayGUID
581
582 end
583
584 deck = getObjectFromGUID(deckGUID)
585 muck = getObjectFromGUID(muckGUID)
586 boardobject = getObjectFromGUID(boardobjectGUID)
587 potobject = getObjectFromGUID(potobjectGUID)
588
589 if options.autoclocktime == nil then
590 options.autoclocktime = 5
591 options.autoclock = false
592 options.autofold = false
593 options.clockpausebutton = true
594 end
595
596
597 --[[ Create buttons --]]
598 local button = {}
599
600 --[[ use this button to assign a new deck --]]
601 button.label = 'New\nDeck'
602 button.click_function = "newDeck"
603 button.function_owner = nil
604 button.position = {0, 0.08, 0}
605 button.rotation = {0,180,0}
606 button.width = 525
607 button.height = 525
608 button.font_size = 150
609 newdeckbutton.createButton(button)
610
611 --[[ This button deals cards for each stage of the hand --]]
612 button.label = 'Deal'
613 button.click_function = "deal"
614 button.font_size = 275
615 dealbutton.createButton(button)
616
617
618 --[[ Resets deck and variables --]]
619 button.label = 'Reset'
620 button.click_function = "resetGame"
621 button.rotation = {0, 0, 0}
622 resetbutton.createButton(button)
623
624 --[[ Move bets to pot --]]
625 button.label = 'Collect\nBets'
626 button.click_function = "collectBets"
627 button.font_size = 150
628 collectbutton.createButton(button)
629
630 --[[ Move action text --]]
631 button.label = 'Done'
632 button.font_size = 200
633 button.click_function = "action"
634 actionbutton.createButton(button)
635
636 --[[ Open options menu --]]
637 button.label = 'Options'
638 button.font_size = 150
639 button.click_function = "spawnOptionsPanel"
640 optionsbutton.createButton(button)
641
642 --[[ Set all 'Tileset' (floor tiles used for tables) and 'Board' (various custom objects) to noninteractable. Skips those with variable i=true on their lua scripts. Also gets the overlay based on the obj file url.]]
643 local objects = getAllObjects()
644 local custom = {}
645 for i, v in ipairs (objects) do
646 if v.tag == 'Tileset' then
647 if not v.getVar('i') then
648 v.interactable = false
649 end
650 elseif v.tag == 'Board' then
651 if not v.getVar('i') then
652 v.interactable = false
653 end
654 custom = v.getCustomObject()
655 if custom.mesh == 'https://raw.githubusercontent.com/johnpenny/tts-poker-table-coverings/master/poker-table-boards.obj' then
656 overlay = v
657 end
658 end
659 end
660
661 muck.setColorTint(pottext.TextTool.getFontColor())
662 boardobject.setColorTint(pottext.TextTool.getFontColor())
663
664 --[[ Copy scripts from objects. These are used when objects are respawned with 'Reset Objects' button on the options menu --]]
665 scripts[1] = muck.getLuaScript()
666 scripts[2] = boardobject.getLuaScript()
667 scripts[3] = potobject.getLuaScript()
668
669end
670
671function onSave()
672
673 local tosave = {
674 options = options,
675
676 holedealt = holedealt,
677 dealing = false,
678 players = players,
679 actionon = actionon,
680 playerbets = playerbets,
681 currentbet = currentbet,
682 mainpotchips = mainpotchips,
683 pot = pot,
684 collecting = false,
685 handinprogress = handinprogress,
686
687 deckGUID = deck.getGUID(),
688 muckGUID = muck.getGUID(),
689 potobjectGUID = potobject.getGUID(),
690 boardobjectGUID = boardobject.getGUID(),
691 overlayGUID = overlay.getGUID()
692 }
693
694 return JSON.encode(tosave)
695
696end
697
698
699--[[ deal function: determines whether to deal players' hands, flop, turn, or river --]]
700
701function deal(ob, pl)
702
703 if not Player[pl].admin then
704 return 1
705 end
706
707 if deck == nil or deck == null then
708 print ("No deck assigned. Please assign a deck with the \'New Deck\' button.")
709 return 1
710 end
711
712 if boardobject == nil or boardobject == null then
713 print ('The board object has been lost. Please click the \'Reset Objects\' button on the options panel to reassign.')
714 return 1
715 end
716
717 if muck == nil or muck == null then
718 print ('The muck object has been lost. Please click the \'Reset Objects\' button on the options panel to reassign.')
719 return 1
720 end
721
722 if not dealing then
723 if not holedealt then
724 hole()
725 else
726 local cards = boardzone.getObjects()
727 local x = 0
728 for i, v in ipairs (cards) do
729 if v.tag == "Card" then
730 x = x+1
731 end
732 end
733
734 if x == 0 then
735 flop ()
736 elseif x == 3 then
737 turn ()
738 elseif x == 4 then
739 river ()
740 elseif x == 5 then
741 broadcastToAll('Showtime!', {1, 1, 1})
742 else
743 print("Error: Invalid board")
744 end
745 end
746 end
747
748end
749
750--[[ This function returns an ordered list of seated players who do not have an afk button or busted token.
751 The first entry will be the player to the dealer's left, and the dealer will be the last entry.
752 If the dealer button is not found, returns nil. --]]
753
754function getOrderedListOfPlayers()
755
756 local dealer = nil
757 local afk = {} -- list of afk players
758 local busted = {} -- list of busted players determined by busted tokens in their bet zones (when a player busts out, I usually make them sit out for a few hands before giving them more money)
759 local objects = {} -- list of objects found in the dealerzones
760 local dealerafk = false
761
762 -- First, look for the dealer button. Also, make list of afk players.
763 for i, v in ipairs (colors) do
764 objects = betzones[v].getObjects()
765 for j, w in ipairs (objects) do
766 if w.getName() == "Dealer" then
767 dealer = v
768 elseif w.getName() == "being meguca is suffering" or w.getName() == "Busted" then
769 if not objectExistsInList (busted, v) then
770 busted[#busted+1] = v
771 w.destruct()
772 end
773 elseif w.getName() == 'AFK' then
774 afk[#afk+1] = v
775 end
776 end
777 end
778
779 -- return nil if dealer button not found
780 if not dealer then
781 print ('Dealer button not found.')
782 return nil
783 end
784
785 local seatedplayers = getSeatedPlayers() -- list of seated players, in some random order
786
787 -- make sure dealer button is in front of a seated player
788 for i, v in ipairs (seatedplayers) do
789 if v == dealer then
790 --print ('Dealer: '..dealer)
791 break
792 end
793
794 if i == #seatedplayers then
795 print ('Dealer button not in front of a seated player.')
796 return nil
797 end
798 end
799
800
801 local playersx = {}
802
803 --sort the seatedplayers into playersx list
804 for i, v in ipairs (colors) do
805 for j, w in ipairs (seatedplayers) do
806 if v == w then
807 playersx[#playersx + 1] = w
808 break
809 end
810 end
811 end
812
813
814 --rotate the list so the dealer is the last entry
815 while playersx[#playersx] != dealer do
816 playersx[#playersx+1] = playersx[1] -- copy first entry to end of table
817 table.remove(playersx, 1) -- then remove first entry
818 end
819
820 -- remove busted players from the table
821 for i, v in ipairs (busted) do
822 for j, w in ipairs (playersx) do
823 if w == v then
824 table.remove(playersx, j)
825 end
826 end
827 end
828
829 -- lastly, remove afk players from the table
830
831 local actionoffset = 0
832
833 for i, v in ipairs(afk) do
834 for j, w in ipairs (playersx) do
835 if w == v then
836 if actionoffset == 0 and j <= 2 then
837 actionoffset = actionoffset + 1
838 elseif actionoffset == 1 and j == 1 then
839 actionoffset = actionoffset + 1
840 end
841 --print ('Removing afk player: '..playersx[j])
842 table.remove(playersx, j)
843 if w == dealer then
844 dealerafk = true
845 end
846 break
847 end
848 end
849 end
850
851 for i, v in ipairs (playersx) do
852 playerbets[i] = 0
853 end
854
855 if options.blindsskipafk then
856 actionoffset = 0
857 end
858
859 if actionoffset < 2 then
860 actionon = playersx[2-actionoffset]
861 else
862 actionon = playersx[#playersx]
863 end
864
865 -- set action on the dealer in a heads-up match
866 if #playersx == 2 and not dealerafk then
867 actionon = playersx[1]
868 end
869
870 --return the final table
871 return playersx
872
873end
874
875
876--[[ deal hole --]]
877
878function hole ()
879
880 players = getOrderedListOfPlayers()
881
882 if not players then
883 return 1 -- abort if dealer button is not in front of a seat
884 else
885 dealing = true
886 handinprogress = true
887 hideActionText()
888 calculatePots()
889 startLuaCoroutine(nil, 'holeCoroutine')
890 end
891
892end
893
894function holeCoroutine()
895
896 local deckpos = deck.getPosition()
897 local cards = 0
898
899 if options.gamemode == 'fivestud' or onecard then
900 cards = 1
901 elseif options.gamemode == 'texas' or options.gamemode == 'sevenstud' then
902 cards = 2
903 elseif options.gamemode == 'pineapple' then
904 cards = 3
905 elseif options.gamemode == 'omaha' then
906 cards = 4
907 elseif options.gamemode == 'fivedraw' then
908 cards = 5
909 end
910
911 deck.setPosition({-0.05, 1.4,-1.97}) -- set the deck to the center of the table so dealt cards don't get intercepted by unintended hands
912 for i = 1, cards do
913 for i, v in ipairs (players) do
914 local t = os.clock()
915 deck.dealToColor(1, players[i])
916 while os.clock() < (t + options.dealdelay1) do
917 coroutine.yield(0)
918 end
919 end
920 end
921
922 deck.setPosition(deckpos)
923
924 if onecard then
925 onecard = false
926 dealing = false
927 if not handinprogress then
928 players = {}
929 end
930 return 1
931 end
932
933--[[ This loop exists to delay the call of the function action()
934 I was having problems with a player (the dealer) being folded due to the cards not reaching the hand
935 before the function was called. --]]
936 t = os.clock()
937 while os.clock() < (t + 1) do
938 coroutine.yield(0)
939 end
940
941 holedealt = true
942 dealing = false
943
944 action()
945
946 return 1
947
948end
949
950
951--[[ deal flop --]]
952
953function flop ()
954
955 dealing = true
956 actionon = nil
957 resetBets()
958 hideActionText()
959
960 if options.chatoptions.stage then
961 broadcastToAll('Flop', {0, 1, 1})
962 end
963
964 startLuaCoroutine(nil, 'flopCoroutine')
965
966end
967
968function flopCoroutine ()
969
970 local muckpos = muck.getPosition()
971 local muckrot = muck.getRotation()
972
973 muckpos.y = muckpos.y + 0.5
974 muckrot.x = muckrot.x + 180
975
976 local params = {}
977
978 params.position = muckpos
979 params.rotation = muckrot
980 deck.takeObject(params)
981
982 for i = 1, 3 do
983 local t = os.clock()
984 while os.clock () < t + options.dealdelay2 do
985 coroutine.yield(0)
986 end
987 params.position = getCardPosition(i)
988 params.rotation = boardobject.getRotation()
989 deck.takeObject(params)
990 end
991
992 t = os.clock()
993 while os.clock() < (t + 1) do
994 coroutine.yield(0)
995 end
996
997 dealing = false
998
999 action()
1000
1001 return (1)
1002
1003end
1004
1005--[[ deal turn --]]
1006
1007function turn ()
1008
1009 dealing = true
1010 actionon = nil
1011 resetBets()
1012 calculatePots()
1013 hideActionText()
1014
1015 if options.chatoptions.stage then
1016 broadcastToAll('Turn', {0, 1, 1})
1017 end
1018
1019 startLuaCoroutine(nil, 'turnCoroutine')
1020
1021end
1022
1023function turnCoroutine ()
1024
1025 local muckpos = muck.getPosition()
1026 local muckrot = muck.getRotation()
1027
1028 muckpos.y = muckpos.y + 0.5
1029 muckrot.x = muckrot.x + 180
1030
1031 local params = {}
1032
1033 params.position = muckpos
1034 params.rotation = muckrot
1035 deck.takeObject(params)
1036
1037 local t = os.clock()
1038 while os.clock() < (t + options.dealdelay2) do
1039 coroutine.yield(0)
1040 end
1041
1042 params.position = getCardPosition(4)
1043 params.rotation = boardobject.getRotation()
1044 deck.takeObject(params)
1045
1046 t = os.clock()
1047 while os.clock() < (t + 1) do
1048 coroutine.yield(0)
1049 end
1050
1051 dealing = false
1052
1053 action()
1054
1055 return (1)
1056
1057end
1058
1059--[[ deal river --]]
1060
1061function river ()
1062
1063 dealing = true
1064 actionon = nil
1065 resetBets()
1066 calculatePots()
1067 hideActionText()
1068
1069 if options.chatoptions.stage then
1070 broadcastToAll('River', {0, 1, 1})
1071 end
1072
1073 startLuaCoroutine(nil, 'riverCoroutine')
1074
1075end
1076
1077function riverCoroutine ()
1078
1079 local muckpos = muck.getPosition()
1080 local muckrot = muck.getRotation()
1081
1082 muckpos.y = muckpos.y + 0.5
1083 muckrot.x = muckrot.x + 180
1084
1085 local params = {}
1086
1087 params.position = muckpos
1088 params.rotation = muckrot
1089 deck.takeObject(params)
1090
1091 local t = os.clock()
1092 while os.clock() < (t + options.dealdelay2) do
1093 coroutine.yield(0)
1094 end
1095
1096 params.position = getCardPosition(5)
1097 params.rotation = boardobject.getRotation()
1098 deck.takeObject(params)
1099
1100 t = os.clock()
1101 while os.clock() < (t + 1) do
1102 coroutine.yield(0)
1103 end
1104
1105 dealing = false
1106
1107 action()
1108
1109 return (1)
1110
1111end
1112
1113--[[ returns the card position based on the position and rotation of the boardobject model--]]
1114
1115function getCardPosition(n)
1116 local p = boardobject.getPosition()
1117 local r = boardobject.getRotation()
1118 local s = boardobject.getScale()
1119 n = 3 - n
1120
1121 p.x = p.x - ((math.cos(math.rad(r.y))*2.75) * n) * s.x
1122 p.z = p.z + ((math.sin(math.rad(r.y))*2.75) * n) * s.z
1123 p.y = p.y + 0.5
1124
1125 return p
1126end
1127--[[ looks for a deck of 52 cards in the specified scripting zone (I used the white player's bet zone) and makes it the new deck object --]]
1128function newDeck (ob, pl)
1129
1130 if not Player[pl].admin then
1131 return 1
1132 end
1133
1134 obj = betzones.White.getObjects()
1135 for i, v in ipairs (obj) do
1136 if v.tag == "Deck" then
1137 if v.getQuantity() == 52 then
1138 deck = {}
1139 deck = getObjectFromGUID(v.getGUID())
1140 print ("New deck assigned.")
1141 return 1
1142 end
1143 end
1144 end
1145
1146 print ("Valid deck not found. Please place a 52-card poker deck inside the white player's bet square try again.") -- it only gets to this line if a deck isn't found in the above loop
1147
1148
1149end
1150
1151--[[ reset the deck and variables --]]
1152
1153function resetGame (ob, pl)
1154
1155 if dealing then
1156 return 1
1157 end
1158
1159 if not Player[pl].admin then
1160 return 1
1161 end
1162
1163 if deck == nil or deck == null then
1164 print ("No deck assigned. Please assign a deck.")
1165 return 1
1166 end
1167
1168 mainpotchips = initializePot()
1169 afk = {}
1170 dealing = true
1171 for i, v in ipairs (colors) do
1172 for j, w in ipairs (Player[v].getHandObjects()) do
1173 w.setRotation({180, 0, 0})
1174 end
1175 end
1176 deck.reset()
1177 holedealt = false
1178 handinprogress = false
1179 players = {}
1180 actionon = nil
1181 currentbet = 0
1182 pot = 0
1183 pottext.setValue('Pot: $'.. tostring(pot))
1184 currentbettext.setValue('Current bet: $'..tostring(currentbet))
1185 playerbets = {}
1186 hideActionText()
1187 if clock ~= nil and clock ~= null then
1188 clock.destruct()
1189 end
1190
1191 startLuaCoroutine(nil, 'resetGameCoroutine')
1192
1193end
1194
1195function resetMuck(zone)
1196
1197 if not deck then
1198 return 1
1199 end
1200
1201 local obj = zone.getObjects()
1202 local deck_pos = deck.getPosition()
1203 local deck_rot = deck.getRotation()
1204
1205 deck_pos.y = deck_pos.y + 0.5
1206
1207 for i, v in ipairs (obj) do
1208 if v.tag == "Card" or v.tag == "Deck" then
1209 if v ~= deck then
1210 v.setPositionSmooth(deck_pos)
1211 v.setRotation(deck_rot)
1212 deck_pos.y = deck_pos.y + 0.1
1213 end
1214 end
1215 end
1216 zone.destruct()
1217end
1218
1219function resetGameCoroutine()
1220
1221 local params = {}
1222 params.position = {0, 1, 0}
1223 params.rotation = {0, 0, 0}
1224 params.scale = {70, 1, 27}
1225 params.type = "ScriptingTrigger"
1226 params.callback = "resetMuck"
1227 params.params = {zone}
1228
1229 local zone = spawnObject(params)
1230
1231 local t = os.clock()
1232
1233
1234 --[[ Print an error and unassign deck if it doesn't have 52 cards after 3 seconds --]]
1235 while deck.getQuantity() < 52 do
1236 if os.clock() > (t + 3) then
1237 print ('Error: Deck missing cards. Unassigned current deck. Please assign new deck')
1238 deck = nil
1239 dealing = false
1240 return 1
1241 end
1242 coroutine.yield(0)
1243 end
1244
1245 --[[ Print an error and unassign deck if it has more than 52 cards --]]
1246 if deck.getQuantity() > 52 then
1247 print ('Error: Too many cards in deck. Unassigned current deck. Please assign new deck.')
1248 deck = nil
1249 dealing = false
1250 return 1
1251 end
1252
1253 deck.shuffle()
1254
1255 t = os.clock()
1256 while os.clock() < (t + 1) do
1257 coroutine.yield(0)
1258 end
1259
1260 dealing = false
1261
1262 return (1)
1263
1264end
1265
1266--[[ move all chips in bet zones into the main pot --]]
1267
1268function collectBets(ob, pl)
1269
1270 --[[ Only host and promoted players can click this button --]]
1271 if not Player[pl].admin then
1272 return 1
1273 end
1274
1275 --[[ Make sure the potobject exists before running function --]]
1276 if potobject == nil or potobject == null then
1277 print ('The pot object has been lost. Please click the \'Reset Objects\' button on the options panel to reassign.')
1278 return 1
1279 end
1280
1281 printstring = printstring..'collect'
1282
1283 if clock ~= nil and clock ~= null then
1284 clock.destruct()
1285 end
1286
1287 if options.collectmethod == 'move' then
1288 startLuaCoroutine(nil, 'moveBetsToPot')
1289 elseif options.collectmethod == 'convert' then
1290 startLuaCoroutine(nil, 'convertBetsToPot')
1291 elseif options.collectmethod == 'hybrid' then
1292 if pot <= options.hybridthreshold then
1293 startLuaCoroutine(nil, 'moveBetsToPot')
1294 else
1295 startLuaCoroutine(nil, 'convertBetsToPot')
1296 end
1297 end
1298end
1299
1300function moveBetsToPot()
1301
1302 local objects = {} -- table of all objects
1303 local values = {"100", "500", "1000", "misc"}
1304 local chips = {["100"] = {}, ["500"] = {}, ["1000"] = {}, ["misc"] = {}} -- tables of chips
1305 local h = {["100"] = {}, ["500"] = {}, ["1000"] = {}, ["misc"] = {}} -- table of heights for each chip stack
1306
1307 --[[Populate chips tables and corresponding heights--]]
1308 for i, v in pairs (betzones) do
1309 objects = v.getObjects()
1310 for j, w in ipairs (objects) do
1311 if w.tag == "Chip" and not w.held_by_color then
1312 if w.getValue() == 100 or w.getValue() == 500 or w.getValue() == 1000 then
1313 chips[tostring(w.getValue())][#chips[tostring(w.getValue())] + 1] = w
1314
1315 if w.getQuantity() > 0 then
1316 h[tostring(w.getValue())][#h[tostring(w.getValue())] + 1] = w.getQuantity() * 0.135
1317 else
1318 h[tostring(w.getValue())][#h[tostring(w.getValue())] + 1] = 0.163
1319 end
1320 else
1321 chips.misc[#chips.misc + 1] = w
1322 if w.getQuantity() > 0 then
1323 h.misc[#h.misc + 1] = w.getQuantity() * 0.3
1324 else
1325 h.misc[#h.misc + 1] = 0.3
1326 end
1327 end
1328 end
1329 end
1330 end
1331
1332 --[[ Get starting position for each chip stack --]]
1333
1334 updatePotPosition()
1335 local r = potobject.getRotation()
1336 r.x = 0
1337 r.z = 0
1338
1339 --[[ Move chips to pot --]]
1340
1341 for i, v in ipairs (values) do
1342 for j, w in ipairs (chips[v]) do
1343 w.setRotation(r)
1344 w.setPosition(mainpotchips[v])
1345 w.translate({0, 0.1, 0})
1346 mainpotchips[v].y = mainpotchips[v].y + h[v][j]
1347 end
1348 end
1349
1350 for i, v in ipairs (values) do
1351 for j, w in ipairs (h[v]) do
1352 if w == 0.163 then
1353 mainpotchips[v].height = mainpotchips[v].height + 0.135
1354 else
1355 mainpotchips[v].height = mainpotchips[v].height + w
1356 end
1357 end
1358 end
1359
1360 for i = 1, 5 do
1361 coroutine.yield(0)
1362 end
1363
1364 calculatePots()
1365
1366 return 1
1367end
1368
1369function convertBetsToPot()
1370
1371 if convertfailcount > convertfailcountlimit then
1372 convertfailcount = 0
1373 startLuaCoroutine (nil, 'moveBetsToPot')
1374 return 1
1375 end
1376
1377 --[[ Get chip values in bet zones --]]
1378
1379 local objects = {}
1380 local chips1 = {}
1381 local positions1 = {}
1382 local rotations1 = {}
1383
1384 for i, v in pairs (betzones) do
1385 objects = {}
1386 objects = v.getObjects()
1387 for j, w in ipairs (objects) do
1388 if w.tag == 'Chip' then
1389 if w.getValue() or tonumber(w.getName()) > 0 then
1390 chips1[#chips1 + 1] = w
1391 end
1392 end
1393 end
1394 end
1395
1396 for i, v in ipairs (chips1) do
1397 positions1[#positions1 + 1] = v.getPosition()
1398 rotations1[#rotations1 + 1] = v.getRotation()
1399 end
1400
1401 for i = 1, 2 do
1402 coroutine.yield(0)
1403 end
1404
1405 objects = {}
1406 local chips2 = {}
1407 local positions2 = {}
1408 local rotations2 = {}
1409
1410 for i, v in pairs (betzones) do
1411 objects = {}
1412 objects = v.getObjects()
1413 for j, w in ipairs (objects) do
1414 if w.tag == 'Chip' then
1415 if w.getValue() or tonumber(w.getName()) > 0 then
1416 chips2[#chips2 + 1] = w
1417 end
1418 end
1419 end
1420 end
1421
1422 if #chips2 ~= #chips1 then
1423 convertfailcount = convertfailcount + 1
1424 startLuaCoroutine(nil, 'convertBetsToPot')
1425 return 1
1426 end
1427
1428 for i, v in ipairs (chips2) do
1429 positions2[#positions2 + 1] = v.getPosition()
1430 rotations2[#rotations2 + 1] = v.getRotation()
1431 end
1432
1433 --[[ Check chip positions --]]
1434 for i, v in ipairs(positions1) do
1435 if v.x ~= positions2[i].x or v.y ~= positions2[i].y or v.z ~= positions2[i].z then
1436 convertfailcount = convertfailcount + 1
1437 startLuaCoroutine(nil, 'convertBetsToPot')
1438 return 1
1439 end
1440 end
1441
1442 --[[ Check chip rotations --]]
1443 for i, v in pairs(rotations1) do
1444 if v.x ~= rotations2[i].x or v.y ~= rotations2[i].y or v.z ~= rotations2[i].z then
1445 convertfailcount = convertfailcount + 1
1446 startLuaCoroutine(nil, 'convertBetsToPot')
1447 return 1
1448 end
1449 end
1450
1451 local chips = {}
1452 local bets = 0
1453
1454 for i, v in pairs (betzones) do
1455 bets = bets + getChipValues(v, chips)
1456 end
1457
1458
1459 --[[ Spawn new chips in pot --]]
1460 updatePotPosition()
1461 local r = potobject.getRotation()
1462 r.x = 0
1463 r.z = 0
1464 local values = {"$10,000", "$5,000", "1000", "500", "100"}
1465 local benjamins = {["mesh"] = 'http://pastebin.com/raw/QqdA0six', ["diffuse"] = 'http://i.imgur.com/kp8fFK0.jpg'}
1466 local grants = {["mesh"] = 'http://pastebin.com/raw/QqdA0six', ["diffuse"] = 'http://i.imgur.com/QQhHmVP.jpg'}
1467 local params = {}
1468 local custom = {}
1469 params.rotation = r
1470
1471 for i, v in ipairs (values) do
1472
1473 if i == 1 then
1474 params.type = 'Custom_Model'
1475 params.scale = {0.75, 0.75, 0.75}
1476 params.callback = 'applyName'
1477 params.callback_owner = Global
1478 params.params = {v}
1479 custom.mesh = benjamins.mesh
1480 custom.diffuse = benjamins.diffuse
1481 custom.type = 5
1482 custom.material = 1
1483
1484 while bets >= tonumber(v) do
1485 updatePotPosition()
1486 params.position = mainpotchips["misc"]
1487 local obj = spawnObject(params)
1488 obj.setCustomObject(custom)
1489 obj.setName(v)
1490 bets = bets - tonumber(v)
1491 mainpotchips["misc"].height = mainpotchips["misc"].height + 0.3
1492 end
1493 end
1494
1495 if i == 2 then
1496 params.params = {v}
1497 custom.mesh = grants.mesh
1498 custom.diffuse = grants.diffuse
1499 while bets >= tonumber(v) do
1500 updatePotPosition()
1501 params.position = mainpotchips["misc"]
1502 local obj = spawnObject(params)
1503 obj.setCustomObject(custom)
1504 obj.setName(v)
1505 bets = bets - tonumber(v)
1506 mainpotchips["misc"].height = mainpotchips["misc"].height + 0.3
1507 end
1508 end
1509
1510 if i > 2 then
1511 params.scale = {1, 1, 1}
1512 params.type = 'Chip_'..v
1513 params.callback = nil
1514 params.params = nil
1515 while bets >= tonumber(v) do
1516 updatePotPosition()
1517 params.position = mainpotchips[v]
1518 spawnObject(params)
1519 bets = bets - tonumber(v)
1520 mainpotchips[v].height = mainpotchips[v].height + 0.135
1521 end
1522 end
1523 end
1524
1525
1526 --[[ Destroy old chips --]]
1527 for i, v in ipairs (chips) do
1528 v.destruct()
1529 end
1530
1531 --[[ Wait five frames to allow chips to spawn before updating pot values --]]
1532 for i = 1, 5 do
1533 coroutine.yield(0)
1534 end
1535
1536 calculatePots()
1537
1538 convertfailcount = 0
1539
1540 return 1
1541end
1542
1543function objectExistsInList(list, object)
1544 for i, v in ipairs(list) do
1545 if v == object then
1546 return true
1547 end
1548 end
1549 return false
1550end
1551
1552function action (ob, pl)
1553
1554 if pl then
1555 if not Player[pl].admin and pl ~= actionon then
1556 return 1
1557 end
1558 end
1559
1560 calculatePots()
1561
1562 -- abort function if action toggled off
1563 if not options.actiontoggle then
1564 return 1
1565 end
1566
1567 --[[ Check action player's bet to make sure it's greater than or equal to current bet --]]
1568 if actionon and actionon == pl then
1569 if getChipValues(betzones[actionon], {}) < currentbet and getChipValues(tablezones[actionon], {}) > 0 and Player[actionon].getHandObjects()[1] then
1570 broadcastToColor('You must match or raise the current bet of $'..currentbet, actionon, {1, 1, 1})
1571 if not Player[pl].admin then
1572 return 1
1573 end
1574 end
1575 end
1576
1577 --[[ Destroy the clock if it exists --]]
1578
1579 if clock ~= nil and clock ~= null then
1580 clock.destruct()
1581 clock = null
1582 end
1583
1584 --[[ abort function and hide text if no players --]]
1585
1586 if #players == 0 then
1587 hideActionText()
1588 return 1
1589 end
1590
1591 local cb = currentbet
1592
1593 --[[ Remove player from list if they don't have cards --]]
1594
1595 if actionon then
1596 if not Player[actionon].getHandObjects()[1] then
1597 for i, v in ipairs (players) do
1598 if v == actionon then
1599 table.remove(players, i)
1600 if i > 1 then
1601 actionon = players[i-1]
1602 else
1603 actionon = players[#players]
1604 end
1605 break
1606 end
1607 end
1608 end
1609
1610 --[[ or if they have no money (all in) --]]
1611 if actionon then
1612 if getChipValues(tablezones[actionon], {}) == 0 then
1613 printstring = printstring..'allin'..actionon
1614 if getChipValues(betzones[actionon], {}) > cb then
1615 cb = getChipValues(betzones[actionon], {})
1616 end
1617 for i, v in ipairs (players) do
1618 if v == actionon then
1619 table.remove(players, i)
1620 if i > 1 then
1621 actionon = players[i-1]
1622 else
1623 actionon = players[#players]
1624 end
1625 break
1626 end
1627 end
1628 end
1629 if not actionon then
1630 hideActionText()
1631 return 1
1632 end
1633 end
1634 if #players == 0 then
1635 return 1
1636 end
1637 end
1638
1639 -- set actionon to next player
1640 if not actionon then
1641 actionon = players[1]
1642 else
1643 for i, v in ipairs (players) do
1644 if actionon == v then
1645 if players[i+1] then
1646 actionon = players[i+1]
1647 else
1648 actionon = players[1]
1649 end
1650 break
1651 end
1652 end
1653 end
1654
1655 -- check new player's hand for cards. remove from list if none and run function again.
1656
1657 if actionon then
1658 if not Player[actionon].getHandObjects()[1] then
1659 for i, v in ipairs (players) do
1660 if v == actionon then
1661 table.remove(players, i)
1662 if i > 1 then
1663 actionon = players[i-1]
1664 else
1665 actionon = players[#players]
1666 end
1667 action()
1668 return 1
1669 end
1670 end
1671 end
1672 end
1673
1674 --[[ Hide text and abort if there is one player and no bet to call --]]
1675
1676 if #players == 1 and getChipValues(betzones[actionon], {}) >= cb then
1677 hideActionText()
1678 return 1
1679 end
1680
1681 printstring = printstring..'action'
1682
1683 -- move actiontext to front of player
1684
1685 local playerhand = getPlayerHandPositionAndRotation(actionon)
1686 actiontext.setValue('Action') -- set action text to say "Action" in case it gets changed (sometimes it changes to "Type here" for some reason)
1687 actiontext.TextTool.setFontColor(fontcolors[actionon]) -- change color of "Action" to player's color
1688
1689 actiontext.setPosition({playerhand['pos_x'] + playerhand['trigger_forward_x'] * 10, 1.33, playerhand['pos_z'] + playerhand['trigger_forward_z'] * 10})
1690 actiontext.setRotation({90, playerhand['rot_y'], 0})
1691
1692 -- move action button to player if playerclickaction is toggled
1693 if options.playerclickaction then
1694 actionbutton.setPosition({playerhand['pos_x'] + playerhand['trigger_forward_x'] * 12, 1.55, playerhand['pos_z'] + playerhand['trigger_forward_z'] * 12})
1695 actionbutton.setRotation({0, playerhand['rot_y'] + 180, 0})
1696 end
1697
1698 -- spawn clock if autoclock
1699 if options.autoclock then
1700 spawnClock()
1701 end
1702end
1703
1704function actionToggle(ob, pl)
1705 if not Player[pl].admin then
1706 return 1
1707 end
1708
1709 if options.actiontoggle then
1710 options.actiontoggle = false
1711 hideActionText()
1712 print ('Action text toggled off. The button can still be used to update pot and current bet values.')
1713 else
1714 options.actiontoggle = true
1715 print ('Action text toggled on. It will reappear next time action is passed.')
1716 end
1717
1718 optionsHost()
1719end
1720
1721function hideActionText()
1722 actiontext.setPosition({0, -2, 0})
1723end
1724
1725function calculatePots()
1726 startLuaCoroutine(nil, 'calculatePotsCoroutine')
1727end
1728
1729function calculatePotsCoroutine ()
1730
1731 local p = potobject.getPosition()
1732 local r = potobject.getRotation()
1733
1734 p.y = p.y + 4.5
1735
1736 potzones[1].setPosition (p)
1737 potzones[1].setRotation (r)
1738 potzones[1].setScale({9.5, 9, 2})
1739
1740 for i = 1, 3 do
1741 coroutine.yield(0)
1742 end
1743
1744 local bets = 0
1745 local mainpot = 0
1746 local prevpot = pot
1747 local prevbet = currentbet
1748 currentbet = 0
1749 local chips = {}
1750 local better = ''
1751
1752 for i, v in ipairs (colors) do
1753 playerbets[i] = getChipValues(betzones[v], chips)
1754 if playerbets[i] > currentbet then
1755 currentbet = playerbets[i]
1756 better = v
1757 end
1758 bets = bets + playerbets[i]
1759 end
1760
1761 chips = {}
1762 mainpot = getChipValues(potzones[1], chips)
1763
1764 pot = bets + mainpot
1765
1766 -- print the pot value in chat
1767 if pot > prevpot then
1768 printstring = printstring..'pot'
1769 end
1770
1771 -- print the current bet in chat
1772 if currentbet > prevbet then
1773
1774 if prevbet == 0 then
1775 printstring = printstring..'bet'..better
1776 else
1777 printstring = printstring..'raise'..better
1778 end
1779
1780 end
1781
1782 -- display pot value on 3dtexts
1783
1784 pottext.setValue('Pot: $'..tostring(pot))
1785 currentbettext.setValue('Current bet: $'..tostring(currentbet))
1786
1787 printMessages()
1788
1789 return 1
1790
1791end
1792
1793function getChipValues(zone, chips)
1794
1795 local objects = zone.getObjects()
1796 local x = 0
1797
1798 for j, w in ipairs (objects) do
1799 if w.tag == 'Chip' and not objectExistsInList(chips, w) then
1800 chips[#chips+1] = w
1801 if w.getQuantity() < 0 then
1802 if w.getValue() then
1803 x = x + w.getValue()
1804 else
1805 x = x + tonumber(w.getName())
1806 end
1807 else
1808 if w.getValue() then
1809 x = x + (w.getValue() * w.getQuantity())
1810 else
1811 x = x + (tonumber(w.getName()) * w.getQuantity())
1812 end
1813 end
1814 end
1815 end
1816
1817 return x
1818
1819end
1820
1821function resetBets()
1822 playerbets = {}
1823 for i, v in ipairs (players) do
1824 playerbets[i] = 0
1825 end
1826 currentbet = 0
1827end
1828
1829--[[ Spawn panel with host options buttons --]]
1830function spawnOptionsPanel(ob, pl)
1831
1832 if not Player[pl].admin then
1833 return 1
1834 end
1835
1836 if optionspanel then
1837 destroyOptionsPanel()
1838 return 1
1839 end
1840
1841 local params = {}
1842 params.type = 'Custom_Model'
1843 params.callback = 'optionsMain'
1844 params.position = {-4.5, 4.45, -25}
1845 params.scale = {2, 1, 2}
1846 params.rotation = {0, 180, 0}
1847
1848 optionspanel = spawnObject(params)
1849
1850 local custom = {}
1851 custom.mesh = 'http://pastebin.com/raw/avCFwn0Y'
1852 custom.collider = 'http://pastebin.com/raw/avCFwn0Y'
1853 custom.specular_intensity = 0
1854 custom.type = 4
1855
1856 optionspanel.setCustomObject(custom)
1857
1858 optionspanel.lock()
1859 optionspanel.interactable = false
1860 optionspanel.setColorTint({0, 0, 0})
1861
1862 startLuaCoroutine(nil, 'addSelfDestruct')
1863
1864end
1865
1866--[[ Add buttons to panel --]]
1867
1868function optionsMain(ob, pl)
1869
1870 if pl then
1871 if not Player[pl].admin then
1872 return 1
1873 end
1874 end
1875
1876 optionspanel.clearButtons()
1877
1878 if colorball ~= nil and colorball ~= null then
1879 colorball.destruct()
1880 end
1881
1882 local button = {}
1883
1884 button.width = 150
1885 button.height = 150
1886 button.label = '☒'
1887 button.font_size = 125
1888 button.click_function = 'destroyOptionsPanel'
1889 button.position = {1.75, 0.05, -1.8}
1890 optionspanel.createButton(button)
1891
1892 button.width = 1000
1893 button.height = 200
1894 button.label = 'Host Settings'
1895 button.click_function = 'optionsHost'
1896 button.font_size = 150
1897 button.position = {0, 0.05, -1.5}
1898
1899 optionspanel.createButton(button)
1900
1901 button.width = 1000
1902 button.height = 200
1903 button.label = 'Chat Settings'
1904 button.click_function = 'optionsChat'
1905 button.font_size = 150
1906 button.position = {0, 0.05, -1}
1907 optionspanel.createButton(button)
1908
1909 button.width = 600
1910 button.height = 200
1911 button.label = 'Themes'
1912 button.click_function = 'optionsThemes'
1913 button.font_size = 150
1914 button.position = {0, 0.05, -0.5}
1915 optionspanel.createButton(button)
1916
1917 button.label = 'Deal one card'
1918 button.width = 800
1919 button.font_size = 100
1920 button.position = {-1, 0.05, 0.5}
1921 button.click_function = 'dealOneCard'
1922 optionspanel.createButton(button)
1923
1924 button.label = 'Clock'
1925 button.width = 800
1926 button.font_size = 150
1927 button.position = {1, 0.05, 0.5}
1928 button.click_function = 'spawnClock'
1929 optionspanel.createButton(button)
1930
1931 button.label = '«'
1932 button.width = 100
1933 button.height = 100
1934 button.font_size = 100
1935 button.click_function = 'decreaseClockTime5'
1936 button.position = {0.4, 0.05, 0.85}
1937 optionspanel.createButton(button)
1938
1939 button.label = '‹'
1940 button.click_function = 'decreaseClockTime1'
1941 button.position = {0.6, 0.05, 0.85}
1942 optionspanel.createButton(button)
1943
1944 button.label = tostring(options.clocktime)
1945 button.width = 300
1946 button.click_function = 'doNothing'
1947 button.position = {1, 0.05, 0.85}
1948 optionspanel.createButton(button)
1949
1950 button.label = '›'
1951 button.width = 100
1952 button.click_function = 'increaseClockTime1'
1953 button.position = {1.4, 0.05, 0.85}
1954 optionspanel.createButton(button)
1955
1956 button.label = '»'
1957 button.click_function = 'increaseClockTime5'
1958 button.position = {1.6, 0.05, 0.85}
1959 optionspanel.createButton(button)
1960
1961 button.label = 'Fold Player'
1962 button.width = 800
1963 button.height = 200
1964 button.font_size = 150
1965 button.position = {1, 0.05, 1.5}
1966 button.click_function = 'foldPlayer'
1967 optionspanel.createButton(button)
1968end
1969
1970function dealOneCard(ob, pl)
1971 if pl then
1972 if not Player[pl].admin and pl ~= actionon then
1973 return 1
1974 end
1975 end
1976
1977 if deck == nil or deck == null then
1978 print ("No deck assigned. Please assign a deck with the \'New Deck\' button.")
1979 return 1
1980 end
1981
1982 if not dealing then
1983 if not handinprogress then
1984 players = getOrderedListOfPlayers()
1985 end
1986
1987 if not players then
1988 return 1
1989 end
1990
1991 onecard = true
1992 dealing = true
1993 startLuaCoroutine(nil, 'holeCoroutine')
1994 end
1995end
1996
1997--[[ If the rewind button is used while the options menu is open, the black square will remain and be non-interactable. This script is added to it so it self-destructs in that event. --]]
1998function addSelfDestruct()
1999 for i = 1, 5 do
2000 coroutine.yield(0)
2001 end
2002 if optionspanel ~= nil and optionspanel ~= null then
2003 optionspanel.setLuaScript('function onload() self.destruct() end')
2004 end
2005 return 1
2006end
2007
2008function optionsHost(ob, pl)
2009 if pl then
2010 if not Player[pl].admin then
2011 return 1
2012 end
2013 end
2014
2015 optionspanel.clearButtons()
2016
2017 local button = {}
2018 local s = ''
2019
2020 button.width = 150
2021 button.height = 150
2022 button.label = '☒'
2023 button.font_size = 125
2024 button.click_function = 'destroyOptionsPanel'
2025 button.position = {1.75, 0.05, -1.8}
2026 optionspanel.createButton(button)
2027
2028 button.width = 150
2029 button.height = 150
2030 button.label = 'â—„'
2031 button.font_size = 125
2032 button.click_function = 'optionsMain'
2033 button.position = {-1.75, 0.05, -1.8}
2034 optionspanel.createButton(button)
2035
2036 if options.actiontoggle then
2037 button.label = '☑ Action'
2038 else
2039 button.label = 'â–¡ Action'
2040 end
2041 button.font_size = 75
2042 button.width = 350
2043 button.height = 100
2044 button.click_function = 'actionToggle'
2045 button.position = {-1.5, 0.05, -1.5}
2046 optionspanel.createButton(button)
2047
2048 if options.actiontoggle then
2049 if options.playerclickaction then
2050 button.label = 'â””Players'
2051 else
2052 button.label = 'â””Host'
2053 end
2054 button.width = 350
2055 button.font_size = 75
2056 button.click_function = 'togglePlayerClickAction'
2057 button.position = {-1.5, 0.05, -1.25}
2058 optionspanel.createButton(button)
2059
2060 if options.autoclock then
2061 button.label = '☑ Autoclock'
2062 else
2063 button.label = 'â–¡ Autoclock'
2064 end
2065 button.position = {-1.35, 0.05, -1.0}
2066 button.width = 500
2067 button.click_function = 'toggleAutoclock'
2068 optionspanel.createButton(button)
2069
2070 if options.autoclock then
2071 button.label = '‹'
2072 button.width = 100
2073 button.click_function = 'decreaseAutoclockTime'
2074 button.position = {-1.7, 0.05, -0.75}
2075 optionspanel.createButton(button)
2076
2077 button.label = tostring(options.autoclocktime)
2078 button.width = 200
2079 button.position = {-1.35, 0.05, -0.75}
2080 button.click_function = 'doNothing'
2081 optionspanel.createButton(button)
2082
2083 button.label = '›'
2084 button.width = 100
2085 button.click_function = 'increaseAutoclockTime'
2086 button.position = {-1.0, 0.05, -0.75}
2087 optionspanel.createButton(button)
2088
2089 if options.clockpausebutton then
2090 button.label = '☑ Pause button'
2091 else
2092 button.label = '□ Pause button'
2093 end
2094 button.width = 600
2095 button.position = {-1.35, 0.05, -0.5}
2096 button.click_function = 'toggleAutoclockPauseButton'
2097 optionspanel.createButton(button)
2098 end
2099
2100 if options.autofold then
2101 button.label = '☑ Autofold'
2102 else
2103 button.label = 'â–¡ Autofold'
2104 end
2105 button.width = 500
2106 button.position = {-0.35, 0.05, -1.0}
2107 button.click_function = 'toggleAutofold'
2108 optionspanel.createButton(button)
2109 end
2110
2111 if options.collectmethod == 'move' then
2112 button.label = 'Collect method: Move'
2113 button.width = 800
2114 elseif options.collectmethod == 'convert' then
2115 button.label = 'Collect method: Convert'
2116 button.width = 850
2117 elseif options.collectmethod == 'hybrid' then
2118 button.label = 'Collect method: Hybrid:'
2119 button.width = 850
2120 end
2121 button.click_function = 'changeCollectMethod'
2122 button.position = {-1, 0.05, 0.5}
2123 optionspanel.createButton(button)
2124
2125 if options.collectmethod == 'hybrid' then
2126 button.label = '«'
2127 button.width = 100
2128 button.click_function = 'decreaseHybridThreshold1000'
2129 button.position = {0.0, 0.05, 0.5}
2130 optionspanel.createButton(button)
2131
2132 button.label = '‹'
2133 button.click_function = 'decreaseHybridThreshold100'
2134 button.position = {0.2, 0.05, 0.5}
2135 optionspanel.createButton(button)
2136
2137 button.label = '$'..tostring(options.hybridthreshold)
2138 button.width = 350
2139 button.click_function = 'doNothing'
2140 button.position = {0.65, 0.05, 0.5}
2141 optionspanel.createButton(button)
2142
2143 button.label = '›'
2144 button.width = 100
2145 button.click_function = 'increaseHybridThreshold100'
2146 button.position = {1.1, 0.05, 0.5}
2147 optionspanel.createButton(button)
2148
2149 button.label = '»'
2150 button.click_function = 'increaseHybridThreshold1000'
2151 button.position = {1.3, 0.05, 0.5}
2152 optionspanel.createButton(button)
2153 end
2154
2155 if options.blindsskipafk then
2156 button.label = '☑ Blinds Skip AFK'
2157 else
2158 button.label = 'â–¡ Blinds Skip AFK'
2159 end
2160 button.width = 650
2161 button.click_function = 'toggleBlindsSkipAFK'
2162 button.position = {-0.375, 0.05, -1.5}
2163 optionspanel.createButton(button)
2164
2165 if options.gamemode == 'omaha' then
2166 s = 'â–º'
2167 else
2168 s = ''
2169 end
2170 button.label = s..'Omaha Hold\'em'
2171 button.width = 650
2172 button.click_function = 'setGameModeOmaha'
2173 button.position = {1.0, 0.05, -1.0}
2174 optionspanel.createButton(button)
2175
2176 if options.gamemode == 'pineapple' then
2177 s = 'â–º'
2178 else
2179 s = ''
2180 end
2181 button.label = s..'Pineapple'
2182 button.width = 700
2183 button.click_function = 'setGameModePineapple'
2184 button.position = {1.0, 0.05, -1.25}
2185 optionspanel.createButton(button)
2186
2187 if options.gamemode == 'texas' then
2188 s = 'â–º'
2189 else
2190 s = ''
2191 end
2192 button.label = s..'Texas Hold\'em'
2193 button.width = 600
2194 button.click_function = 'setGameModeTexas'
2195 button.position = {1.0, 0.05, -1.5}
2196 optionspanel.createButton(button)
2197
2198 button.label = 'Reset Objects'
2199 button.click_function = 'checkAndRespawnObjects'
2200 button.position = {-1.0, 0.05, 1}
2201 optionspanel.createButton(button)
2202end
2203
2204function optionsChat(ob, pl)
2205
2206 if pl then
2207 if not Player[pl].admin then
2208 return 1
2209 end
2210 end
2211
2212 optionspanel.clearButtons()
2213
2214 local button = {}
2215
2216 button.width = 150
2217 button.height = 150
2218 button.label = '☒'
2219 button.font_size = 125
2220 button.click_function = 'destroyOptionsPanel'
2221 button.position = {1.75, 0.05, -1.8}
2222 optionspanel.createButton(button)
2223
2224 button.width = 150
2225 button.height = 150
2226 button.label = 'â—„'
2227 button.font_size = 125
2228 button.click_function = 'optionsMain'
2229 button.position = {-1.75, 0.05, -1.8}
2230 optionspanel.createButton(button)
2231
2232 button.width = 650
2233 button.height = 150
2234 button.font_size = 75
2235 if options.chatoptions.actionmessage then
2236 button.label = '☑ Action message'
2237 else
2238 button.label = 'â–¡ Action message'
2239 end
2240 button.click_function = 'toggleActionMessage'
2241 button.position = {-1.0, 0.05, -1.5}
2242 optionspanel.createButton(button)
2243
2244 button.width = 700
2245 button.height = 150
2246 button.font_size = 75
2247 if options.chatoptions.actionbroadcast then
2248 button.label = '☑ Action broadcast'
2249 else
2250 button.label = 'â–¡ Action broadcast'
2251 end
2252 button.click_function = 'toggleActionBroadcast'
2253 button.position = {-1.0, 0.05, -1.25}
2254 optionspanel.createButton(button)
2255
2256 button.width = 600
2257 button.height = 150
2258 button.font_size = 75
2259 if options.chatoptions.currentbetmessage then
2260 button.label = '☑ Current bet'
2261 else
2262 button.label = 'â–¡ Current bet'
2263 end
2264 button.click_function = 'toggleCurrentBetMessage'
2265 button.position = {1.0, 0.05, -1.5}
2266 optionspanel.createButton(button)
2267
2268 button.width = 600
2269 button.height = 150
2270 button.font_size = 75
2271 if options.chatoptions.better then
2272 button.label = '☑ └Better/raiser'
2273 else
2274 button.label = 'â–¡ â””Better/raiser'
2275 end
2276 button.click_function = 'toggleBetter'
2277 button.position = {1.0, 0.05, -1.25}
2278 if options.chatoptions.currentbetmessage then
2279 optionspanel.createButton(button)
2280 end
2281
2282 button.width = 700
2283 button.height = 150
2284 button.font_size = 75
2285 if options.chatoptions.allinbroadcast then
2286 button.label = '☑ All-in broadcast'
2287 else
2288 button.label = 'â–¡ All-in broadcast'
2289 end
2290 button.click_function = 'toggleAllinBroadcast'
2291 button.position = {1.0, 0.05, -1.0}
2292 optionspanel.createButton(button)
2293
2294 button.height = 150
2295 button.font_size = 75
2296 if options.chatoptions.potmessage == 0 then
2297 button.width = 700
2298 button.label = 'Pot message: Off'
2299 elseif options.chatoptions.potmessage == 1 then
2300 button.width = 1000
2301 button.label = 'Pot message: On collect only'
2302 elseif options.chatoptions.potmessage == 2 then
2303 button.width = 900
2304 button.label = 'Pot message: On change'
2305 end
2306 button.click_function = 'togglePotMessage'
2307 button.position = {1.0, 0.05, -0.75}
2308 optionspanel.createButton(button)
2309
2310 button.width = 850
2311 button.height = 150
2312 button.font_size = 75
2313 if options.chatoptions.stage then
2314 button.label = '☑ Game stage broadcast'
2315 else
2316 button.label = 'â–¡ Game stage broadcast'
2317 end
2318 button.click_function = 'toggleStageBroadcast'
2319 button.position = {-1.0, 0.05, -1.0}
2320 optionspanel.createButton(button)
2321
2322end
2323
2324function optionsThemes(ob, pl)
2325 if pl then
2326 if not Player[pl].admin then
2327 return 1
2328 end
2329 end
2330 optionspanel.clearButtons()
2331
2332 local button = {}
2333
2334 button.width = 150
2335 button.height = 150
2336 button.label = '☒'
2337 button.font_size = 125
2338 button.click_function = 'destroyOptionsPanel'
2339 button.position = {1.75, 0.05, -1.8}
2340 optionspanel.createButton(button)
2341
2342 button.width = 150
2343 button.height = 150
2344 button.label = 'â—„'
2345 button.font_size = 125
2346 button.click_function = 'optionsMain'
2347 button.position = {-1.75, 0.05, -1.8}
2348 optionspanel.createButton(button)
2349
2350 button.label = 'Set Font Color'
2351 button.width = 600
2352 button.font_size = 75
2353 button.click_function = 'changeFontColor'
2354 button.position = {-0.75, 0.05, -1.75}
2355 optionspanel.createButton(button)
2356
2357 button.label = 'Set Overlay Color'
2358 button.width = 600
2359 button.click_function = 'changeTableColor'
2360 button.position = {0.75, 0.05, -1.75}
2361 optionspanel.createButton(button)
2362
2363 button.label = 'Darken Overlay'
2364 button.width = 600
2365 button.click_function = 'darkenOverlay'
2366 button.position = {-0.75, 0.05, -1.5}
2367 optionspanel.createButton(button)
2368
2369 button.label = 'Lighten Overlay'
2370 button.width = 600
2371 button.click_function = 'lightenOverlay'
2372 button.position = {0.75, 0.05, -1.5}
2373 optionspanel.createButton(button)
2374
2375
2376
2377 --[[ spawn theme buttons --]]
2378 for i, v in ipairs (themes) do
2379 local s = ''
2380 if i == themeindex then
2381 s = 'â–º'
2382 end
2383 button.width = (((string.len(themes[i].label) + string.len(s)) * 40) + 0 )
2384 button.height = 100
2385 button.font_size = 65
2386 button.label = themes[i].label..s
2387 button.click_function = 'setTheme'..tostring(i)
2388 button.position = {-1.75, 0.05, (-1 + ((i-1) * 0.25))}
2389 optionspanel.createButton(button)
2390 end
2391
2392 --[[ spawn subtheme buttons --]]
2393 for i, v in ipairs (themes[themeindex]) do
2394 local s = ''
2395 if i == subthemeindex then
2396 s = 'â–º'
2397 end
2398 button.width = (((string.len(themes[themeindex][i].label) + string.len(s)) * 40) + 0)
2399 button.height = 100
2400 button.label = themes[themeindex][i].label..s
2401 button.click_function = 'setSubtheme'..tostring(i)
2402 button.position = {-0.75, 0.05, (-1 + ((i-1) * 0.25))}
2403 optionspanel.createButton(button)
2404 end
2405
2406 --[[ spawn diffuse buttons --]]
2407 for i, v in ipairs (themes[themeindex][subthemeindex]) do
2408 button.width = ((string.len(themes[themeindex][subthemeindex][i].label) * 35) + 0)
2409 button.height = 100
2410 button.label = themes[themeindex][subthemeindex][i].label
2411 button.click_function = 'overlay'..tostring(i)
2412 button.position = {1, 0.05, (-1 + ((i-1) * 0.25))}
2413 optionspanel.createButton(button)
2414 end
2415
2416 if colorball == nil or colorball == null then
2417 local params = {}
2418 local p = optionspanel.getPosition()
2419 params.position = {p.x, p.y, p.z + 3.5}
2420 params.type = 'go_game_piece_white'
2421 params.scale = {0.5, 0.5, 0.5}
2422
2423 colorball = spawnObject(params)
2424 local color = pottext.TextTool.getFontColor()
2425 colorball.lock()
2426 colorball.setColorTint(color)
2427 colorball.setDescription('Change my color tint, then click \'Font Color\' button to change color of text fonts.')
2428 end
2429
2430end
2431
2432function spawnClock(ob, pl)
2433 if pl then
2434 if not Player[pl].admin then
2435 return 1
2436 end
2437 end
2438
2439 if clock ~= nil and clock ~= null then
2440 if pl then
2441 clock.Clock.setValue(options.clocktime + 1)
2442 clock.Clock.pauseStart()
2443 clock.clearButtons()
2444 end
2445 return 1
2446 end
2447
2448 local params = {}
2449 if actionon then
2450 local playerhand = getPlayerHandPositionAndRotation(actionon)
2451
2452 params.position = {playerhand['pos_x'] + playerhand['trigger_forward_x'] * 8, 0.5, playerhand['pos_z'] + playerhand['trigger_forward_z'] * 8}
2453 params.rotation = {90, playerhand['rot_y'], 0}
2454 else
2455 params.position = {0, 0.5, -4}
2456 params.rotation = {90, 180, 0}
2457 end
2458
2459 params.type = 'Digital_Clock'
2460 params.callback = 'setClockTimer'
2461 if pl then
2462 params.params = {pl}
2463 else
2464 params.params = nil
2465 end
2466
2467 clock = spawnObject(params)
2468
2469end
2470
2471function setClockTimer(ob, pl)
2472 clock.lock()
2473
2474 if pl then
2475 clock.Clock.setValue(options.clocktime + 1)
2476 else
2477 clock.Clock.setValue(options.autoclocktime + 1)
2478 end
2479
2480 clock.Clock.pauseStart()
2481
2482 if options.autoclock and options.clockpausebutton and not pl then
2483 local button = {}
2484 button.rotation = {90, 180, 0}
2485 button.position = {-0.3, 0.5, -0.15}
2486 button.font_size = 60
2487 button.width = 200
2488 button.height = 50
2489 button.label = 'Pause'
2490 button.click_function = 'pauseClock'
2491 clock.createButton(button)
2492 end
2493 startLuaCoroutine(nil, 'setClockTimerCoroutine')
2494end
2495
2496function setClockTimerCoroutine()
2497
2498 local clockGUID = clock.getGUID()
2499
2500 while clock ~= nil and clock ~= null and clock.Clock.getValue() > 0 do
2501 coroutine.yield(0)
2502 end
2503
2504 local t = os.clock()
2505
2506 while os.clock() < t+1 do
2507 coroutine.yield(0)
2508 end
2509
2510 if clock ~= nil and clock ~= null then
2511 if clockGUID ~= clock.getGUID() then
2512 return 1
2513 end
2514 else
2515 return 1
2516 end
2517
2518 if options.autofold then
2519 foldPlayer()
2520 end
2521
2522 clock.destruct()
2523
2524 return 1
2525end
2526
2527function toggleAutoclock(ob, pl)
2528 if not Player[pl].admin then
2529 return 1
2530 end
2531
2532 options.autoclock = not options.autoclock
2533 optionsHost()
2534end
2535
2536function toggleAutofold(ob, pl)
2537 if not Player[pl].admin then
2538 return 1
2539 end
2540
2541 options.autofold = not options.autofold
2542 optionsHost()
2543end
2544
2545function decreaseAutoclockTime(ob, pl)
2546 if not Player[pl].admin then
2547 return 1
2548 end
2549
2550 if options.autoclocktime > 1 then
2551 options.autoclocktime = options.autoclocktime - 1
2552 end
2553 optionsHost()
2554end
2555
2556function increaseAutoclockTime(ob, pl)
2557 if not Player[pl].admin then
2558 return 1
2559 end
2560
2561 options.autoclocktime = options.autoclocktime + 1
2562 optionsHost()
2563end
2564
2565function toggleAutoclockPauseButton(ob, pl)
2566 if not Player[pl].admin then
2567 return 1
2568 end
2569
2570 options.clockpausebutton = not options.clockpausebutton
2571 optionsHost()
2572end
2573
2574function pauseClock(ob, pl)
2575 if not Player[pl].admin and pl ~= actionon then
2576 return 1
2577 end
2578
2579 clock.Clock.pauseStart()
2580end
2581
2582function decreaseClockTime5(ob, pl)
2583 if not Player[pl].admin then
2584 return 1
2585 end
2586
2587 if options.clocktime > 5 then
2588 options.clocktime = options.clocktime - 5
2589 else
2590 return 1
2591 end
2592
2593 optionsMain()
2594end
2595function decreaseClockTime1(ob, pl)
2596 if not Player[pl].admin then
2597 return 1
2598 end
2599
2600 if options.clocktime > 1 then
2601 options.clocktime = options.clocktime - 1
2602 else
2603 return 1
2604 end
2605
2606 optionsMain()
2607end
2608function increaseClockTime1(ob, pl)
2609 if not Player[pl].admin then
2610 return 1
2611 end
2612
2613 options.clocktime = options.clocktime + 1
2614
2615 optionsMain()
2616end
2617function increaseClockTime5(ob, pl)
2618 if not Player[pl].admin then
2619 return 1
2620 end
2621
2622 options.clocktime = options.clocktime + 5
2623
2624 optionsMain()
2625end
2626
2627function foldPlayer(ob, pl)
2628
2629 if pl then
2630 if not Player[pl].admin then
2631 return 1
2632 end
2633 end
2634
2635 if muck == nil or muck == null then
2636 print ('The muck object has been lost. Please click the \'Reset Objects\' button on the options panel to reassign.')
2637 return 1
2638 end
2639
2640 if actionon then
2641 local cards = Player[actionon].getHandObjects()
2642 local p = muck.getPosition()
2643 local r = muck.getRotation()
2644 p.y = p.y + 0.25
2645 r.x = 180
2646 r.z = 0
2647
2648 for i, v in ipairs (cards) do
2649 v.setRotation(r)
2650 v.setPosition(p)
2651 v.translate({0, 0.1, 0})
2652 p.y = p.y + 0.01
2653 end
2654 end
2655
2656 startLuaCoroutine(nil, 'delayedAction')
2657end
2658
2659function delayedAction()
2660 for i = 1, 2 do
2661 coroutine.yield(0)
2662 end
2663
2664 action()
2665 return 1
2666end
2667
2668function decreaseHybridThreshold1000(ob, pl)
2669 if not Player[pl].admin then
2670 return 1
2671 end
2672
2673 if options.hybridthreshold > 1000 then
2674 options.hybridthreshold = options.hybridthreshold - 1000
2675 end
2676
2677 optionsHost()
2678end
2679
2680function decreaseHybridThreshold100(ob, pl)
2681 if not Player[pl].admin then
2682 return 1
2683 end
2684
2685 if options.hybridthreshold > 100 then
2686 options.hybridthreshold = options.hybridthreshold - 100
2687 end
2688
2689 optionsHost()
2690end
2691
2692function increaseHybridThreshold100(ob, pl)
2693 if not Player[pl].admin then
2694 return 1
2695 end
2696
2697 options.hybridthreshold = options.hybridthreshold + 100
2698
2699 optionsHost()
2700end
2701
2702function increaseHybridThreshold1000(ob, pl)
2703 if not Player[pl].admin then
2704 return 1
2705 end
2706
2707 options.hybridthreshold = options.hybridthreshold + 1000
2708
2709 optionsHost()
2710end
2711
2712function doNothing()
2713end
2714
2715function changeFontColor(ob, pl)
2716
2717 if not Player[pl].admin then
2718 return 1
2719 end
2720
2721 local color = colorball.getColorTint()
2722 pottext.TextTool.setFontColor(color)
2723 currentbettext.TextTool.setFontColor(color)
2724 muck.setColorTint(color)
2725 boardobject.setColorTint(color)
2726end
2727
2728function changeTableColor(ob, pl)
2729
2730 if not Player[pl].admin then
2731 return 1
2732 end
2733
2734 local color = colorball.getColorTint()
2735 overlay.setColorTint(color)
2736end
2737
2738function setGameModeTexas(ob, pl)
2739
2740 if not Player[pl].admin or options.gamemode == 'texas' then
2741 return 1
2742 end
2743
2744 options.gamemode = 'texas'
2745 printToAll('Game mode set to Texas Hold\'em. See rules in the notebook if you don\'t know how to play.', {1, 1, 1})
2746
2747 optionsHost()
2748end
2749function setGameModeOmaha(ob, pl)
2750
2751 if not Player[pl].admin or options.gamemode == 'omaha' then
2752 return 1
2753 end
2754
2755 options.gamemode = 'omaha'
2756 printToAll('Game mode set to Omaha Hold\'em. See rules in the notebook if you don\'t know how to play.', {1, 1, 1})
2757
2758 optionsHost()
2759end
2760function setGameModePineapple(ob, pl)
2761
2762 if not Player[pl].admin or options.gamemode == 'pineapple' then
2763 return 1
2764 end
2765
2766 options.gamemode = 'pineapple'
2767 printToAll('Game mode set to Pineapple. See rules in the notebook if you don\'t know how to play.', {1, 1, 1})
2768
2769 optionsHost()
2770end
2771function setGameModeFiveCard(ob, pl)
2772
2773 if not Player[pl].admin or options.gamemode == 'fivecard' then
2774 return 1
2775 end
2776
2777 options.gamemode = 'fivedraw'
2778 printToAll('Game mode set to Five Card Draw. See rules in the notebook if you don\'t know how to play.', {1, 1, 1})
2779
2780 optionsHost()
2781end
2782
2783function getParams(obj)
2784 local params = {}
2785 params.position = obj.getPosition()
2786 params.scale = obj.getScale()
2787 params.rotation = obj.getRotation()
2788
2789 return params
2790end
2791
2792function setTheme1(ob, pl)
2793
2794 if not Player[pl].admin then
2795 return 1
2796 end
2797
2798 themeindex = 1
2799 subthemeindex = 1
2800 optionsThemes()
2801end
2802
2803function setTheme2(ob, pl)
2804
2805 if not Player[pl].admin then
2806 return 1
2807 end
2808
2809 themeindex = 2
2810 subthemeindex = 1
2811 optionsThemes()
2812end
2813
2814function setTheme3(ob, pl)
2815
2816 if not Player[pl].admin then
2817 return 1
2818 end
2819
2820 themeindex = 3
2821 subthemeindex = 1
2822 optionsThemes()
2823end
2824
2825function setTheme4(ob, pl)
2826
2827 if not Player[pl].admin then
2828 return 1
2829 end
2830
2831 themeindex = 4
2832 subthemeindex = 1
2833 optionsThemes()
2834end
2835
2836function setTheme5(ob, pl)
2837
2838 if not Player[pl].admin then
2839 return 1
2840 end
2841
2842 themeindex = 5
2843 subthemeindex = 1
2844 optionsThemes()
2845end
2846
2847function setTheme6(ob, pl)
2848
2849 if not Player[pl].admin then
2850 return 1
2851 end
2852
2853 themeindex = 6
2854 subthemeindex = 1
2855 optionsThemes()
2856end
2857
2858function setTheme7(ob, pl)
2859
2860 if not Player[pl].admin then
2861 return 1
2862 end
2863
2864 themeindex = 7
2865 subthemeindex = 1
2866 optionsThemes()
2867end
2868
2869function setTheme8(ob, pl)
2870
2871 if not Player[pl].admin then
2872 return 1
2873 end
2874
2875 themeindex = 8
2876 subthemeindex = 1
2877 optionsThemes()
2878end
2879
2880function setTheme9(ob, pl)
2881
2882 if not Player[pl].admin then
2883 return 1
2884 end
2885
2886 themeindex = 9
2887 subthemeindex = 1
2888 optionsThemes()
2889end
2890
2891function setTheme10(ob, pl)
2892
2893 if not Player[pl].admin then
2894 return 1
2895 end
2896
2897 themeindex = 10
2898 subthemeindex = 1
2899 optionsThemes()
2900end
2901
2902function setTheme11(ob, pl)
2903
2904 if not Player[pl].admin then
2905 return 1
2906 end
2907
2908 themeindex = 11
2909 subthemeindex = 1
2910 optionsThemes()
2911end
2912
2913function setTheme12(ob, pl)
2914
2915 if not Player[pl].admin then
2916 return 1
2917 end
2918
2919 themeindex = 12
2920 subthemeindex = 1
2921 optionsThemes()
2922end
2923
2924function setSubtheme1(ob, pl)
2925
2926 if not Player[pl].admin then
2927 return 1
2928 end
2929
2930 subthemeindex = 1
2931 optionsThemes()
2932end
2933function setSubtheme2(ob, pl)
2934
2935 if not Player[pl].admin then
2936 return 1
2937 end
2938
2939 subthemeindex = 2
2940 optionsThemes()
2941end
2942function setSubtheme3(ob, pl)
2943
2944 if not Player[pl].admin then
2945 return 1
2946 end
2947
2948 subthemeindex = 3
2949 optionsThemes()
2950end
2951function setSubtheme4(ob, pl)
2952
2953 if not Player[pl].admin then
2954 return 1
2955 end
2956
2957 subthemeindex = 4
2958 optionsThemes()
2959end
2960function setSubtheme5(ob, pl)
2961
2962 if not Player[pl].admin then
2963 return 1
2964 end
2965
2966 subthemeindex = 5
2967 optionsThemes()
2968end
2969function setSubtheme6(ob, pl)
2970
2971 if not Player[pl].admin then
2972 return 1
2973 end
2974
2975 subthemeindex = 6
2976 optionsThemes()
2977end
2978function setSubtheme7(ob, pl)
2979
2980 if not Player[pl].admin then
2981 return 1
2982 end
2983
2984 subthemeindex = 7
2985 optionsThemes()
2986end
2987function setSubtheme8(ob, pl)
2988
2989 if not Player[pl].admin then
2990 return 1
2991 end
2992
2993 subthemeindex = 8
2994 optionsThemes()
2995end
2996function setSubtheme9(ob, pl)
2997
2998 if not Player[pl].admin then
2999 return 1
3000 end
3001
3002 subthemeindex = 9
3003 optionsThemes()
3004end
3005function setSubtheme10(ob, pl)
3006
3007 if not Player[pl].admin then
3008 return 1
3009 end
3010
3011 subthemeindex = 10
3012 optionsThemes()
3013end
3014function setSubtheme11(ob, pl)
3015
3016 if not Player[pl].admin then
3017 return 1
3018 end
3019
3020 subthemeindex = 11
3021 optionsThemes()
3022end
3023function setSubtheme12(ob, pl)
3024
3025 if not Player[pl].admin then
3026 return 1
3027 end
3028
3029 subthemeindex = 12
3030 optionsThemes()
3031end
3032
3033function overlay1 (ob, pl)
3034
3035 if not Player[pl].admin then
3036 return 1
3037 end
3038
3039 changeOverlay(themes[themeindex][subthemeindex][1].diffuse)
3040
3041end
3042function overlay2 (ob, pl)
3043
3044 if not Player[pl].admin then
3045 return 1
3046 end
3047
3048 changeOverlay(themes[themeindex][subthemeindex][2].diffuse)
3049
3050end
3051function overlay3 (ob, pl)
3052
3053 if not Player[pl].admin then
3054 return 1
3055 end
3056
3057 changeOverlay(themes[themeindex][subthemeindex][3].diffuse)
3058
3059end
3060function overlay4 (ob, pl)
3061
3062 if not Player[pl].admin then
3063 return 1
3064 end
3065
3066 changeOverlay(themes[themeindex][subthemeindex][4].diffuse)
3067
3068end
3069function overlay5 (ob, pl)
3070
3071 if not Player[pl].admin then
3072 return 1
3073 end
3074
3075 changeOverlay(themes[themeindex][subthemeindex][5].diffuse)
3076
3077end
3078function overlay6 (ob, pl)
3079
3080 if not Player[pl].admin then
3081 return 1
3082 end
3083
3084 changeOverlay(themes[themeindex][subthemeindex][6].diffuse)
3085
3086end
3087function overlay7 (ob, pl)
3088
3089 if not Player[pl].admin then
3090 return 1
3091 end
3092
3093 changeOverlay(themes[themeindex][subthemeindex][7].diffuse)
3094
3095end
3096function overlay8 (ob, pl)
3097
3098 if not Player[pl].admin then
3099 return 1
3100 end
3101
3102 changeOverlay(themes[themeindex][subthemeindex][8].diffuse)
3103
3104end
3105function overlay9 (ob, pl)
3106
3107 if not Player[pl].admin then
3108 return 1
3109 end
3110
3111 changeOverlay(themes[themeindex][subthemeindex][9].diffuse)
3112
3113end
3114function overlay10 (ob, pl)
3115
3116 if not Player[pl].admin then
3117 return 1
3118 end
3119
3120 changeOverlay(themes[themeindex][subthemeindex][10].diffuse)
3121
3122end
3123function overlay11 (ob, pl)
3124
3125 if not Player[pl].admin then
3126 return 1
3127 end
3128
3129 changeOverlay(themes[themeindex][subthemeindex][11].diffuse)
3130
3131end
3132function overlay12 (ob, pl)
3133
3134 if not Player[pl].admin then
3135 return 1
3136 end
3137
3138 changeOverlay(themes[themeindex][subthemeindex][12].diffuse)
3139
3140end
3141
3142function changeOverlay(diffuse)
3143
3144 local custom = overlay.getCustomObject()
3145 local params = getParams(overlay)
3146 custom.diffuse = diffuse
3147 params.type = 'Custom_Model'
3148 local s = params.scale
3149 params.scale = {1, 1, 1}
3150 overlay.destruct()
3151
3152 overlay = spawnObject(params)
3153 overlay.setCustomObject(custom)
3154 overlay.setScale(s)
3155 overlay.lock()
3156 overlay.interactable = false
3157
3158end
3159
3160--[[ Destroy options panel --]]
3161function destroyOptionsPanel(ob, pl)
3162
3163 if pl and not Player[pl].admin then
3164 return 1
3165 end
3166
3167 optionspanel.clearButtons()
3168 optionspanel.destruct()
3169 optionspanel = nil
3170 if colorball ~= nil and colorball ~= null then
3171 colorball.destruct()
3172 end
3173end
3174
3175function toggleBlindsSkipAFK(ob, pl)
3176
3177 if not Player[pl].admin then
3178 return 1
3179 end
3180
3181 options.blindsskipafk = not options.blindsskipafk
3182
3183 optionsHost()
3184end
3185
3186function darkenOverlay(ob, pl)
3187
3188 if not Player[pl].admin then
3189 return 1
3190 end
3191
3192 local color = overlay.getColorTint()
3193 for i, v in pairs (color) do
3194 if v >= 0.05 then
3195 color[i] = v - 0.05
3196 else
3197 color[i] = 0
3198 end
3199 end
3200
3201 overlay.setColorTint(color)
3202end
3203
3204function lightenOverlay(ob, pl)
3205
3206 if not Player[pl].admin then
3207 return 1
3208 end
3209
3210 local color = overlay.getColorTint()
3211 for i, v in pairs (color) do
3212 if v <= 1.95 then
3213 color[i] = v + 0.05
3214 else
3215 color[i] = 2
3216 end
3217 end
3218
3219 overlay.setColorTint(color)
3220end
3221
3222function changeCollectMethod(ob, pl)
3223 if not Player[pl].admin then
3224 return 1
3225 end
3226
3227 if options.collectmethod == 'move' then
3228 options.collectmethod = 'convert'
3229 print('Collect method set to: Convert. Bets will now be converted up when collected.')
3230 elseif options.collectmethod == 'convert' then
3231 options.collectmethod = 'hybrid'
3232 print('Collect method set to: Hybrid. Bets will be converted up once the pot is over $'..options.hybridthreshold..'.')
3233 elseif options.collectmethod == 'hybrid' then
3234 options.collectmethod = 'move'
3235 print('Collect method set to: Move. Bets will be moved into the pot.')
3236 end
3237
3238 optionsHost()
3239end
3240
3241function checkAndRespawnObjects(ob, pl)
3242 if not Player[pl].admin then
3243 return 1
3244 end
3245
3246 local meshes = {'http://pastebin.com/raw/133e1Z0L', 'http://pastebin.com/raw/U9rtcyua', 'http://pastebin.com/raw/uvvaV5Np', 'https://raw.githubusercontent.com/johnpenny/tts-poker-table-coverings/master/poker-table-boards.obj'}
3247 local diffuses = {'http://i.imgur.com/QinS8Hc.png', 'http://i.imgur.com/hIKi7Mq.png', 'http://i.imgur.com/novIseH.png', 'http://i.imgur.com/jPnTE9e.png'}
3248 local allobjects = getAllObjects()
3249 local objects = {'muck', 'boardobject', 'potobject', 'overlay'}
3250 local objectnames = {'Muck', 'Board', 'Pot', 'Overlay'}
3251 local objectexists = {false, false, false, false} -- muck, board, pot, overlay
3252 local positions = {{-9.175, 1.35, -1.9}, {0, 1.35, -2}, {0, 1.35, -7.5}, {0, 0.7, 0}}
3253 local custom = {}
3254 local params = {}
3255
3256 -- mark unlost objects as existing
3257 for i, v in ipairs (objects) do
3258 if Global.getVar(v) ~= nil and Global.getVar(v) ~= null then
3259 objectexists[i] = true
3260 --print (objectnames[i]..' exists.')
3261 end
3262 end
3263
3264 -- search for objects and reassign any that are found
3265 for i, v in ipairs (allobjects) do
3266 custom = v.getCustomObject()
3267 for j, w in ipairs (meshes) do
3268 if custom.mesh == w then
3269 if not objectexists[j] then
3270 Global.setVar(objects[j] , v)
3271 objectexists[j] = true
3272 print(objectnames[j]..' reassigned.')
3273 end
3274 end
3275 end
3276 end
3277
3278 -- respawn nonexistent objects
3279 for i, v in ipairs (objectexists) do
3280 if not v then
3281 params.type = 'Custom_Model'
3282 params.position = positions[i]
3283 params.rotation = {0, 0, 0}
3284
3285 custom.mesh = meshes[i]
3286 custom.diffuse = diffuses[i]
3287 custom.type = 4
3288
3289 local o = spawnObject(params)
3290 o.setCustomObject(custom)
3291
3292 if i ~= 4 then
3293 o.setLuaScript(scripts[i])
3294 else
3295 o.lock()
3296 o.interactable = false
3297 end
3298
3299 Global.setVar(objects[i], o)
3300
3301 print (objectnames[i]..' respawned.')
3302 end
3303 end
3304
3305end
3306
3307function togglePlayerClickAction(ob, pl)
3308 if not Player[pl].admin then
3309 return 1
3310 end
3311
3312 if options.playerclickaction then
3313 options.playerclickaction = false
3314 print ('The Action button will now remain in a static position for the host to click.')
3315
3316 local buttons = actionbutton.getButtons()
3317
3318 buttons[1].label = 'Action'
3319
3320 actionbutton.editButton(buttons[1])
3321 else
3322 options.playerclickaction = true
3323 print ('The action button will now be moved in front of the player whose turn it is to act.')
3324
3325 local buttons = actionbutton.getButtons()
3326
3327 buttons[1].label = 'Done'
3328
3329 actionbutton.editButton(buttons[1])
3330 end
3331
3332 optionsHost()
3333end
3334
3335function toggleEnforcePotLimit(ob, pl)
3336 if not Player[pl].admin then
3337 return 1
3338 end
3339
3340 options.enforcepotlimit = not options.enforcepotlimit
3341
3342 optionsHost()
3343end
3344
3345function toggleEnforceFoldInTurn(ob, pl)
3346 if not Player[pl].admin then
3347 return 1
3348 end
3349
3350 options.enforcefoldinturn = not options.enforcefoldinturn
3351
3352 optionsHost()
3353end
3354
3355function toggleEnforceDoubleRaise(ob, pl)
3356 if not Player[pl].admin then
3357 return 1
3358 end
3359
3360 options.enforcedoubleraise = not options.enforcedoubleraise
3361
3362 optionsHost()
3363end
3364
3365function toggleActionMessage(ob, pl)
3366 if not Player[pl].admin then
3367 return 1
3368 end
3369
3370 options.chatoptions.actionmessage = not options.chatoptions.actionmessage
3371
3372 optionsChat()
3373end
3374
3375function toggleActionBroadcast(ob, pl)
3376 if not Player[pl].admin then
3377 return 1
3378 end
3379
3380 options.chatoptions.actionbroadcast = not options.chatoptions.actionbroadcast
3381
3382 optionsChat()
3383end
3384
3385function toggleStageBroadcast(ob, pl)
3386 if not Player[pl].admin then
3387 return 1
3388 end
3389
3390 options.chatoptions.stage = not options.chatoptions.stage
3391
3392 optionsChat()
3393end
3394
3395function toggleCurrentBetMessage(ob, pl)
3396 if not Player[pl].admin then
3397 return 1
3398 end
3399
3400 options.chatoptions.currentbetmessage = not options.chatoptions.currentbetmessage
3401
3402 optionsChat()
3403end
3404
3405function toggleBetter(ob, pl)
3406 if not Player[pl].admin then
3407 return 1
3408 end
3409
3410 options.chatoptions.better = not options.chatoptions.better
3411
3412 optionsChat()
3413end
3414
3415function toggleAllinBroadcast(ob, pl)
3416 if not Player[pl].admin then
3417 return 1
3418 end
3419
3420 options.chatoptions.allinbroadcast = not options.chatoptions.allinbroadcast
3421
3422 optionsChat()
3423end
3424
3425function togglePotMessage(ob, pl)
3426 if not Player[pl].admin then
3427 return 1
3428 end
3429
3430 if options.chatoptions.potmessage >= 2 then
3431 options.chatoptions.potmessage = 0
3432 else
3433 options.chatoptions.potmessage = options.chatoptions.potmessage + 1
3434 end
3435
3436 optionsChat()
3437end
3438
3439function printMessages()
3440
3441 local p = ''
3442
3443 for i, v in ipairs(colors) do
3444 if string.find(printstring, v) then
3445 p = v
3446 break
3447 end
3448 end
3449
3450 if string.find(printstring, 'bet') or string.find(printstring, 'raise') then
3451 if options.chatoptions.currentbetmessage then
3452 local s = 'Current bet: $'..currentbet
3453 if options.chatoptions.better then
3454 if string.find(printstring, 'bet') then
3455 if Player[p].steam_name then
3456 s = s..', made by '..fontcolors[p].bbcode..Player[p].steam_name..'[ffffff].'
3457 else
3458 s = s..', made by '..fontcolors[p].bbcode..p..'[ffffff].'
3459 end
3460 else
3461 if Player[p].steam_name then
3462 s = s..', raised by '..fontcolors[p].bbcode..Player[p].steam_name..'[ffffff].'
3463 else
3464 s = s..', raised by '..fontcolors[p].bbcode..p..'[ffffff].'
3465 end
3466 end
3467 else
3468 s = s..'.'
3469 end
3470
3471 printToAll(s, {1, 1, 1})
3472 end
3473 end
3474
3475
3476 if options.chatoptions.allinbroadcast and string.find(printstring, 'allin') then
3477 if string.find(printstring, p) then
3478 if Player[p].steam_name then
3479 broadcastToAll (fontcolors[p].bbcode..Player[p].steam_name..'[ffffff] is all in!', {1, 1, 1})
3480 else
3481 broadcastToAll (fontcolors[p].bbcode..p..'[ffffff] is all in!.', {1, 1, 1})
3482 end
3483 end
3484 end
3485
3486 if string.find(printstring, 'action') and actionon then
3487
3488 if options.chatoptions.actionmessage then
3489 if Player[actionon].steam_name then
3490 printToAll ("Action on "..fontcolors[actionon].bbcode..Player[actionon].steam_name..'[ffffff].', {1, 1, 1})
3491 else
3492 printToAll ("Action on "..fontcolors[actionon].bbcode..actionon..'[ffffff].', {1, 1, 1})
3493 end
3494 end
3495
3496 if options.chatoptions.actionbroadcast and Player[actionon].seated then
3497 broadcastToColor("Action on you!", actionon, {1, 0, 0})
3498 end
3499 end
3500
3501 if options.chatoptions.potmessage > 0 then
3502 if (options.chatoptions.potmessage >= 1 and string.find(printstring, 'collect')) or (options.chatoptions.potmessage > 1 and string.find(printstring, 'pot')) then
3503 printToAll('Pot: $'..pot..'.', {1, 1, 1})
3504 end
3505 end
3506
3507 printstring = ''
3508end
3509
3510function initializePot()
3511
3512 local p = -- table containing pot information
3513 {
3514 ["100"] =
3515 {
3516 ["yoffset"] = 0.0825, -- half of the object's height to put its bottom on the surface
3517 ["height"] = 0, -- height of current stack
3518 ["x"] = 0, -- coordinates of stack
3519 ["y"] = 0,
3520 ["z"] = 0
3521 },
3522 ["500"] =
3523 {
3524 ["yoffset"] = 0.0825,
3525 ["height"] = 0,
3526 ["x"] = 0,
3527 ["y"] = 0,
3528 ["z"] = 0
3529 },
3530 ["1000"] =
3531 {
3532 ["yoffset"] = 0.0825,
3533 ["height"] = 0,
3534 ["x"] = 0,
3535 ["y"] = 0,
3536 ["z"] = 0
3537 },
3538 ["misc"] =
3539 {
3540 ["yoffset"] = 0.2,
3541 ["height"] = 0,
3542 ["x"] = 0,
3543 ["y"] = 0,
3544 ["z"] = 0
3545 }
3546 }
3547
3548 return p
3549end
3550
3551function updatePotPosition() -- sets the positions for chip stacks
3552
3553 local p = potobject.getPosition()
3554 local r = potobject.getRotation()
3555
3556 mainpotchips["100"].x = p.x + (math.cos(math.rad(r.y)) * ((1.75 * 2) + 0.25))
3557 mainpotchips["100"].z = p.z - (math.sin(math.rad(r.y)) * ((1.75 * 2) + 0.25))
3558 mainpotchips["100"].y = p.y + mainpotchips["100"].yoffset + mainpotchips["100"].height
3559
3560 mainpotchips["500"].x = p.x + (math.cos(math.rad(r.y)) * (1.75 + 0.25))
3561 mainpotchips["500"].z = p.z - (math.sin(math.rad(r.y)) * (1.75 + 0.25))
3562 mainpotchips["500"].y = p.y + mainpotchips["500"].yoffset + mainpotchips["500"].height
3563
3564 mainpotchips["1000"].x = p.x + (math.cos(math.rad(r.y)) * 0.25)
3565 mainpotchips["1000"].z = p.z - (math.sin(math.rad(r.y)) * 0.25)
3566 mainpotchips["1000"].y = p.y + mainpotchips["1000"].yoffset + mainpotchips["1000"].height
3567
3568 mainpotchips["misc"].x = p.x - (math.cos(math.rad(r.y)) * (2.375 + 0.25))
3569 mainpotchips["misc"].z = p.z + (math.sin(math.rad(r.y)) * (2.375 + 0.25))
3570 mainpotchips["misc"].y = p.y + mainpotchips["misc"].yoffset + mainpotchips["misc"].height
3571
3572end