antonsavov

Untitled

Dec 17th, 2016
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 38.79 KB | None | 0 0
  1. local VERSION = '0.8.3 - Heimkehr harry-fix'
  2. os.loadAPI('tracker')
  3. os.loadAPI('json')
  4.  
  5. print("Starting 20,000 Blocks")
  6.  
  7. DEBUG_MODE = false
  8. local monitor = peripheral.wrap("right")
  9. local ox,oy,oz = commands.getBlockPosition()
  10.  
  11. SPAWN_VILLAGER = false
  12. DO_GRID = true
  13. GRID_HOLE_CHANCE = 0
  14. NUMBER_OF_BUILDZONES = 6
  15. NUMBER_OF_VOCAB = 10
  16. GAME_LENGTH = 600
  17. VOCAB_WIDTH = 27
  18. VOCAB_HEIGHT = 19
  19. BUILDZONE_WIDTH = 62
  20. BUILDZONE_FLOOR_HEIGHT = -1
  21. SPAWN = {
  22. x=12110,
  23. y=57,
  24. z=-1777,
  25. a1=90,
  26. a2=0
  27. }
  28. FIRSTZONE= {
  29. x=11685,
  30. y=57,
  31. z=-1869
  32. }
  33. WAITZONE = {
  34. x=12092,
  35. y=57,
  36. z=-1780,
  37. w=7,
  38. l=7
  39. }
  40. VICTORY_HEIGHT = 30
  41. VICTORY_TOTAL = 50
  42. VICTORY_SPECIFIC = {name='garden',count=101}
  43.  
  44. DEFAULT_REWARD = 'minecraft:emerald 2 0 {display:{Name:"Emerald",Lore:[Trade this to the villager for wool]}}'
  45. WOOL_PER_EMERALD = 64
  46. PICKAXE_USES = 10
  47.  
  48. BLOCKS = {
  49. CAMP_FLOOR = {block='minecraft:sandstone',data=0},
  50. CONSTRUCTION = {block='minecraft:diamond_ore',data=0},
  51. RING = {block='minecraft:diamond_ore',data=0},
  52. DETECT = {block='minecraft:red_sandstone',data=0},
  53. DETECT_DEAD = {block='minecraft:obsidian',data=0},
  54. VOCAB_DETECT = {block="minecraft:quartz_block",data=0},
  55. VOCAB_REPLACE = {block="minecraft:coal_block",data=0},
  56. VICTORY_MARKER = {block="minecraft:emerald_block",data=0},
  57. PLUG = {block="minecraft:lapis_ore",data=0},
  58. PHVFLOOR = {block="minecraft:stone_slab",data=3},
  59. BUILDING_HOUSE = {block="minecraft:wool",data=0},
  60. BUILDING_GARDEN = {block="minecraft:wool",data=13},
  61. BUILDING_WATER = {block="minecraft:wool",data=1},
  62. }
  63.  
  64. --contains a list of all posible Buildzones (build a bit later)
  65. LOCS = {}
  66.  
  67. if DEBUG_MODE then
  68. GAME_LENGTH = 12000
  69. NUMBER_OF_BUILDZONES = 1
  70. end
  71.  
  72. --creates a grid of absoulte references (0,0) (1,0)
  73. function buildGrid(w,h)
  74. local grid = {}
  75. for x=0,w-1 do
  76. for z=0,h-1 do
  77. table.insert(grid,{x=x,z=z})
  78. end
  79. end
  80. return grid
  81. end
  82.  
  83. --sets where and how big the PHV area is
  84. --second number is along the long edge of PHV starting at the spawn side
  85. --first number is along the short edge of PHV starting from the park side
  86. if DEBUG_MODE then
  87. FIRSTZONE= {
  88. x=5,
  89. y=57,
  90. z=-7
  91. }
  92.  
  93. LOCS = buildGrid(1,3)
  94. else
  95. LOCS = buildGrid(11,15)
  96. end
  97.  
  98. --call these to return a proper minecraft item string including adventure mode properties
  99. function houseBlock(quant)
  100. text = BLOCKS.BUILDING_HOUSE.block..' '..quant..' '..BLOCKS.BUILDING_HOUSE.data..' {display:{Name:"House Construction Block",Lore:[Place this against a Diamond to build a house]},CanPlaceOn:["'..BLOCKS.BUILDING_HOUSE.block..'","'..BLOCKS.PLUG.block..'","'..BLOCKS.DETECT.block..'"]}'
  101. return text
  102. end
  103.  
  104. function waterBlock(quant)
  105. text = BLOCKS.BUILDING_WATER.block..' '..quant..' '..BLOCKS.BUILDING_WATER.data..' {display:{Name:"Water Construction Block",Lore:[Place this against a Diamond to build a pond or pool]},CanPlaceOn:["'..BLOCKS.BUILDING_HOUSE.block..'","'..BLOCKS.PLUG.block..'","'..BLOCKS.DETECT.block..'"]}'
  106. return text
  107. end
  108.  
  109. function gardenBlock(quant)
  110. text = BLOCKS.BUILDING_GARDEN.block..' '..quant..' '..BLOCKS.BUILDING_GARDEN.data..' {display:{Name:"Garden Construction Block",Lore:[Place this against a Diamond to build a pond or pool]},CanPlaceOn:["'..BLOCKS.BUILDING_HOUSE.block..'","'..BLOCKS.PLUG.block..'","'..BLOCKS.DETECT.block..'"]}'
  111. return text
  112. end
  113.  
  114. STARTING_ITEMS = {
  115. houseBlock(30), gardenBlock(30),
  116. 'stone_pickaxe 1 '..131-PICKAXE_USES..' {CanDestroy:["'..BLOCKS.BUILDING_HOUSE.block..'"],display:{Name:"Construction Remover",Lore:[Use this to remove up to '..PICKAXE_USES..' pieces of construction material]}}'
  117.  
  118. }
  119.  
  120. REWARDS = {}
  121. --plain singlehouse rewards (costs 4 house, -2+1 activators)
  122. REWARDS[1] = gardenBlock(4)
  123. REWARDS[2] = gardenBlock(4)
  124. REWARDS[3] = gardenBlock(4)
  125. REWARDS[4] = gardenBlock(4)
  126. --extension rise rewards (costs 6 house, -2+1 activators)
  127. REWARDS[5] = gardenBlock(7)
  128. REWARDS[6] = gardenBlock(7)
  129. REWARDS[7] = gardenBlock(7)
  130. REWARDS[8] = gardenBlock(7)
  131. --house bridge rewards (costs 6 house, -3+2 activators)
  132. REWARDS[9] = gardenBlock(10)
  133. REWARDS[10] = gardenBlock(10)
  134. --garden bridge (unused)
  135. REWARDS[11] = gardenBlock(7)
  136. REWARDS[12] = gardenBlock(7)
  137. --extention row house rewards (costs 4 house, 1 activators)
  138. REWARDS[13] = houseBlock(6)
  139. REWARDS[14] = houseBlock(6)
  140. REWARDS[15] = houseBlock(6)
  141. REWARDS[16] = houseBlock(6)
  142. --riser 1
  143. REWARDS[17] = houseBlock(1)
  144. --riser 2
  145. REWARDS[18] = houseBlock(1)
  146. --filler garden
  147. REWARDS[19] = houseBlock(1)
  148. --filler house plaza
  149. REWARDS[20] = gardenBlock(3)
  150. --extention-farm (like extension rise) (costs 6 garden, -2 activators)
  151. REWARDS[21] = houseBlock(3)
  152. REWARDS[22] = houseBlock(3)
  153. REWARDS[23] = houseBlock(3)
  154. REWARDS[24] = houseBlock(3)
  155. --extension-garden (like extension row house)rewards (costs 3 garden, 1 activators)
  156. REWARDS[25] = "minecraft:emerald"
  157. REWARDS[26] = "minecraft:emerald"
  158. REWARDS[27] = "minecraft:emerald"
  159. REWARDS[28] = "minecraft:emerald"
  160. --L-shaped small business agriculture (costs 6 garden, -3+2 activators)
  161. REWARDS[29] = "minecraft:emerald 2"
  162. REWARDS[30] = "minecraft:emerald 2"
  163. REWARDS[31] = "minecraft:emerald 2"
  164. REWARDS[32] = "minecraft:emerald 2"
  165. --L-shaped small business urban (costs 6 housing, -3+2 activators)
  166. REWARDS[33] = gardenBlock(6)
  167. REWARDS[34] = gardenBlock(6)
  168. REWARDS[35] = gardenBlock(6)
  169. REWARDS[36] = gardenBlock(6)
  170. --allotments (costs 4 garden, -2 activators)
  171. REWARDS[37] = houseBlock(2)
  172. REWARDS[38] = houseBlock(2)
  173. REWARDS[39] = houseBlock(2)
  174. REWARDS[40] = houseBlock(2)
  175.  
  176. DEFAULT_NAME = 'default-vocab'
  177. VOCAB_NAMES = {
  178. 'freestand-house',
  179. 'freestand-house',
  180. 'freestand-house',
  181. 'freestand-house',
  182. 'dbl-ext-house',
  183. 'dbl-ext-house',
  184. 'dbl-ext-house',
  185. 'dbl-ext-house',
  186. 'bridge-house',
  187. 'bridge-house',
  188. 'bridge-garden',
  189. 'bridge-garden',
  190. 'ext-house',
  191. 'ext-house',
  192. 'ext-house',
  193. 'ext-house',
  194. 'riser-1',
  195. 'riser-2',
  196. 'city-garden',
  197. 'city-plaza',
  198. 'dbl-ext-garden',
  199. 'dbl-ext-garden',
  200. 'dbl-ext-garden',
  201. 'dbl-ext-garden',
  202. 'ext-garden',
  203. 'ext-garden',
  204. 'ext-garden',
  205. 'ext-garden',
  206. 'corner-garden',
  207. 'corner-garden',
  208. 'corner-garden',
  209. 'corner-garden',
  210. 'corner-house',
  211. 'corner-house',
  212. 'corner-house',
  213. 'corner-house',
  214. 'freestand-garden',
  215. 'freestand-garden',
  216. 'freestand-garden',
  217. 'freestand-garden',
  218. 'zoo',
  219. 'bookstore',
  220. 'greenhouse',
  221. 'fablab'
  222. }
  223.  
  224. --constructor for player object so that data structure is consistant
  225. function newPlayerData(name,x,y,z)
  226. local p = {
  227. name = name,
  228. x=x,
  229. y=y,
  230. z=z
  231. }
  232. return p
  233. end
  234.  
  235. --return a list of all players in the game world as player objects
  236. local function getAllPos(selector)
  237. local result, message = commands.tp("@a["..selector.."]","~ ~ ~")
  238. local names = {}
  239. if result == true then
  240. for i,result in ipairs(message) do
  241. local wordpattern = "[^, ]+"
  242. local numberpattern = "[%-% ]%d+[%.]%d+"
  243. local words,numbers = {},{}
  244.  
  245. for word in string.gmatch(result, wordpattern) do
  246. table.insert(words,word)
  247. end
  248.  
  249. for number in string.gmatch(result, numberpattern) do table.insert(numbers,number) end
  250.  
  251. local coords = {
  252. x = math.floor(numbers[1]),
  253. y = math.floor(numbers[2]),
  254. z = math.floor(numbers[3])
  255. }
  256. local name = words[2]
  257. table.insert(names,newPlayerData(name,coords.x,coords.y,coords.z))
  258. --print("Player Found - getAllPos")
  259. end
  260. end
  261. return names
  262. end
  263.  
  264. --sort table by random
  265. local function shuffleTable( t )
  266. local rand = math.random
  267. assert( t, "shuffleTable() expected a table, got nil" )
  268. local iterations = #t
  269. local j
  270.  
  271. for i = iterations, 2, -1 do
  272. j = rand(i)
  273. t[i], t[j] = t[j], t[i]
  274. end
  275. end
  276.  
  277. --returns a list of player objects containing all players who are standing on the given block, and who also are in the given selection
  278. local function getAllOnBlockType(block,selector)
  279. local result, message = commands.exec("execute @a["..selector.."] ~ ~ ~ detect ~ ~-1 ~ "..block.." -1 tp @p[r=1] ~ ~ ~")
  280. local names = {}
  281. if result == true then
  282. for i,result in ipairs(message) do
  283. local wordpattern = "[^, ]+"
  284. local numberpattern = "[%-% ]%d+[%.]%d+"
  285. local words,numbers = {},{}
  286.  
  287. for word in string.gmatch(result, wordpattern) do table.insert(words,word) end
  288. for number in string.gmatch(result, numberpattern) do table.insert(numbers,number) end
  289.  
  290. if numbers[1] and numbers[2] and numbers[3] then
  291. local coords = {
  292. x = math.floor(numbers[1]),
  293. y = math.floor(numbers[2]),
  294. z = math.floor(numbers[3])
  295. }
  296. local name = words[2]
  297. table.insert(names,newPlayerData(name,coords.x,coords.y,coords.z))
  298. print("Found a player - getOnBlock")
  299. else
  300. print("Error: Coordinate Numbers were missing")
  301. end
  302. end
  303. end
  304. return names
  305. end
  306.  
  307. --gives a player a squid egg with their name on it. Removes all spawn eggs first
  308. local function giveSquid(name)
  309. commands.clear(name,'spawn_egg')
  310. commands.give(name,'spawn_egg 1 94 {CanPlaceOn:["'..BLOCKS.PHVFLOOR.block..'","'..BLOCKS.CAMP_FLOOR.block..'"],display:{Name:"Heimkehrer - '..name..'",Lore:[Use this on the floor to return to spawn]}}')
  311. end
  312.  
  313. --returns a list of squid objects and their names
  314. local function getSquids()
  315. local result, message = commands.exec("execute @e[type=Squid] ~ ~ ~ tp @e[r=1] ~ ~ ~")
  316. local names = {}
  317. if result == true then
  318. for i,result in ipairs(message) do
  319. local wordpattern = "[^, ]+"
  320. local numberpattern = "[%-% ]%d+[%.]%d+"
  321. local words,numbers = {},{}
  322.  
  323. for word in string.gmatch(result, wordpattern) do table.insert(words,word) print(word) end
  324. for number in string.gmatch(result, numberpattern) do table.insert(numbers,number) end
  325.  
  326. if numbers[1] and numbers[2] and numbers[3] then
  327. local coords = {
  328. x = math.floor(numbers[1]),
  329. y = math.floor(numbers[2]),
  330. z = math.floor(numbers[3])
  331. }
  332. local name = words[4]
  333. table.insert(names,newPlayerData(name,coords.x,coords.y,coords.z))
  334. print("Found a player - getOnBlock "..name)
  335. else
  336. print("Error: Coordinate Numbers were missing")
  337. end
  338. end
  339. end
  340. return names
  341. end
  342.  
  343. local function removePlayerFromKew(game,playername)
  344. for _,kew in pairs(game.queues) do
  345. for index, player in ipairs(kew.playerlist) do
  346. if player.name == playername then
  347. table.remove(kew.playerlist,index)
  348. end
  349. end
  350. if #kew.playerlist == 0 and kew.phase == 2 then
  351. --game can be ended as no players are left
  352. kew.timer = 0
  353. end
  354. end
  355. end
  356.  
  357. local function movePlayerToSpawn(playername)
  358. respawnPlayer(playername)
  359. commands.async.tp(playername,SPAWN.x,SPAWN.y,SPAWN.z,SPAWN.a1,SPAWN.a2)
  360. commands.async.tellraw(playername,'["",{"text":"TELEPORTED: You used your Heimkehrer","color":"blue"}]')
  361. end
  362.  
  363. --takes a list of squids and deals with all those players, moving them back to spawn and removing them from game
  364. --also gives them a new squid
  365. local function dealWithSquidders(game,squids)
  366. for _,squid in pairs(squids) do
  367. --remove player from current game if in game
  368. removePlayerFromKew(game,squid.name)
  369. --teleport them back to spawn
  370. movePlayerToSpawn(squid.name)
  371. --give a new squid
  372. giveSquid(squid.name)
  373. --particle effects
  374. --teleport message
  375. end
  376. --kill all squids
  377. if #squids>0 then
  378. commands.tp("@e[type=Squid]",100000,200,100000)
  379. commands.kill("@e[type=Squid]")
  380. os.sleep(#squids*0.2)
  381. end
  382. end
  383.  
  384.  
  385.  
  386.  
  387. --creates a village with special items
  388. local function spawnVillager(x,y,z)
  389. commands.summon("Villager",x,y,z,'{Invulnerable:1,CustomName:Wool_Seller,Profession:2,Career:1,CareerLevel:6,Offers:{Recipes:[ {buy:{id:emerald,Count:1},sell:{id:wool,Count:'..WOOL_PER_EMERALD..',tag:{CanPlaceOn:["minecraft:diamond_block","minecraft:clay","minecraft:wool","minecraft:stained_hardened_clay"]}}}, {buy:{id:emerald,Count:1},sell:{id:stone_pickaxe,Count:1,Damage:'..131-PICKAXE_USES..',tag:{CanDestroy:["minecraft:wool"]}}} ]}}')
  390. end
  391.  
  392. --displays a subtitle of time to a selection of players
  393. local function displayTime(selector,minutes,seconds)
  394. --commands.title("@a["..selector.."]","subtitle",'{text:"Time left: '..minutes..":"..seconds..'",color:red,bold:false,underlined:false,italic:false,strikethrough:false,obfuscated:false}')
  395. commands.async.xp("-1000000L","@a["..selector.."]")
  396. local secondstot = (minutes * 60) + seconds
  397. commands.async.xp(tostring(secondstot).."L","@a["..selector.."]")
  398. end
  399.  
  400. --displays a title to a selection of players
  401. local function displayTitle(selector,text)
  402. commands.async.title("@a["..selector.."]","title",'{text:"'..text..'"}')
  403. end
  404.  
  405. --simply runs displayTitle on a list of players
  406. local function displayTitleToGroup(playerlist,text)
  407. for i,player in ipairs(playerlist) do
  408. displayTitle("name="..player.name,text)
  409. end
  410. end
  411.  
  412. --simply runs displayTime on a list of players
  413. local function displayTimeToGroup(playerlist,minutes,seconds)
  414. for i,player in ipairs(playerlist) do
  415. displayTime("name="..player.name,minutes,seconds)
  416. end
  417. end
  418.  
  419. --teleports a list of players to an exact place and sends them a message about it
  420. local function teleportToPoint(x,y,z,playerlist,clear,text)
  421. for i,player in ipairs(playerlist) do
  422. player.x = x
  423. player.y = y
  424. player.z = z
  425. commands.async.gamemode(2,player.name)
  426. if clear then
  427. commands.async.clear(player.name,"wool")
  428. commands.async.clear(player.name,"stone_pickaxe")
  429. end
  430. commands.tp("@a[name="..player.name.."]",x,y,z)
  431. commands.async.tellraw(player.name,'["",{"text":"'..text..'","color":"blue"}]')
  432. end
  433. end
  434.  
  435. --teleports a list of players to a given buildzone
  436. local function teleportToZone(buildzone,playerlist,text)
  437. teleportToPoint(buildzone.x+2+(buildzone.w/2),buildzone.y+5,buildzone.z+2+(buildzone.w/2),playerlist,true,text)
  438.  
  439. end
  440.  
  441. --gives the same list of items to a list of players
  442. local function giveItems(playerlist,itemlist)
  443. local given = 0
  444. for i,player in ipairs(playerlist) do
  445. --commands.async.clear(player.name)
  446. for j,item in ipairs(itemlist) do
  447. commands.async.give("@a[name="..player.name.."]",item)
  448. given = given +1
  449. end
  450. giveSquid(player.name)
  451. end
  452. return given
  453. end
  454.  
  455. --a multi builder which uses the vocab constructor to create sets of vocab
  456. local function makeVocabZones(quant,w)
  457. local x,y,z = ox,oy,oz+6
  458. local result = {}
  459. local namecount = 1
  460. for i=0,quant-1 do
  461. for k=0,3 do
  462. local zpos = i-4
  463. local ypos = k
  464. print("vocab at X")
  465. print(x-(2*w)-6)
  466. print("and Z")
  467. print(z+((w+1)*zpos))
  468. local nextVocab = newVocabZone(x-(2*w)-6,y+(ypos*(VOCAB_HEIGHT+3)),z+((w+1)*zpos),w,REWARDS[namecount] or DEFAULT_REWARD,VOCAB_NAMES[namecount] or DEFAULT_NAME)
  469. table.insert(result,nextVocab)
  470. namecount = namecount +1
  471. end
  472. end
  473. return result
  474. end
  475.  
  476. --finds the next free location in a given area.
  477. --giving force as True will mean it overrides the first location no matter what
  478. local function findNextLoc(width,zones,force)
  479. local x,y,z = 0,0,0
  480. for i,loc in ipairs(LOCS) do
  481. x,y,z = FIRSTZONE.x+(loc.x*(width+1)),FIRSTZONE.y,FIRSTZONE.z+(-loc.z*(width+1))
  482. local result,message = commands.testforblock(x,y+BUILDZONE_FLOOR_HEIGHT,z,"minecraft:air")
  483. if force then result = true end
  484. local zonefree = true
  485. for i,zone in ipairs(zones) do
  486. if zone.x == x and zone.z == z then
  487. zonefree = false
  488. end
  489. end
  490. --print("next position free is ",loc.x*width,oy,loc.z*width)
  491. --if result then print("true") else print("false") end
  492. if result and zonefree then
  493. --print("using loc: ",loc.x,loc.z)
  494. return x,y,z
  495. end
  496. end
  497. return nil,nil,nil
  498.  
  499. end
  500.  
  501. --relocates a buildzone to a new coordinate safely
  502. --avoids overlapping with other buildzones
  503. function moveBuildzone(buildzone,zones)
  504. local x,y,z = findNextLoc(buildzone.w,zones)
  505. if x and y and z then
  506. print("moved buildzone from "..buildzone.x..","..buildzone.z.." to "..x..","..y)
  507. local w = buildzone.w
  508. buildzone.x,buildzone.y,buildzone.z = x,y+BUILDZONE_FLOOR_HEIGHT,z
  509. buildzone.selector = "x="..x..",y="..tostring(y-1)..",z="..z..",dx="..w..",dy=256,dz="..w
  510. buildzone.structures = {} --a list of all vocabularies which have been contructed
  511. else
  512. print("buildzone at "..buildzone.x..","..buildzone.z.." stayed where it is")
  513. end
  514. end
  515.  
  516. --multi builder to create sets of buildzones using the buildzone constructor
  517. local function makeBuildzones(quant,vocab,width,height)
  518. local result = {}
  519. for i=1,quant do
  520. local x,y,z = findNextLoc(width,result)
  521. if x and y and z then
  522. --print("made new buildzone at",x,y,z)
  523. table.insert(result,newBuildZone(x,y+height,z,width,vocab))
  524. else
  525. --print("failed to make new buildzone")
  526. end
  527. end
  528.  
  529. local remaining = NUMBER_OF_BUILDZONES - #result
  530.  
  531. for i=1, remaining do
  532. local x,y,z = findNextLoc(width,result,true)
  533. if x and y and z then
  534. --print("forced new buildzone at",x,y,z)
  535. table.insert(result,newBuildZone(x,y+height,z,width,vocab))
  536. else
  537. print("failed to force new buildzone")
  538. end
  539. end
  540.  
  541.  
  542. return result
  543. end
  544.  
  545. --vocab constructor. Enforces some data structure
  546. function newVocabZone(x,y,z,w,reward,name)
  547. local nvz = {}
  548. nvz.x ,nvz.y ,nvz.z ,nvz.w = x,y,z,w
  549.  
  550. nvz.cx = nvz.x - nvz.w - 2
  551. nvz.cy = nvz.y
  552. nvz.cz = nvz.z
  553. nvz.name = name
  554. nvz.reward = reward
  555.  
  556. return nvz
  557.  
  558. end
  559.  
  560. --buildzone constructor. Enforces some data structure
  561. function newBuildZone(x,y,z,w,vocabZones)
  562. local nbz = {}
  563. nbz.x ,nbz.y ,nbz.z ,nbz.w = x,y,z,w
  564. nbz.selector = "x="..x..",y="..(y-5)..",z="..z..",dx="..w..",dy=256,dz="..w
  565. nbz.structures = {} --a list of all vocabularies which have been contructed
  566. nbz.waitingForCheck = {}
  567. nbz.highest = 0
  568. nbz.vocab = vocabZones
  569.  
  570. return nbz
  571. end
  572.  
  573. --kew constructor. Enforces some data structure
  574. function newQueue(buildzone,maxplayers)
  575. local q = {}
  576. q.timer = 1
  577. q.phase = 1
  578.  
  579. q.victory = false
  580. q.phases = {
  581. {
  582. name = "Selecting Players",
  583. length = 25,
  584. displaylength = 15
  585. },
  586. {
  587. name = "Game In Progress",
  588. length = GAME_LENGTH,
  589. displaylength = 70
  590. },
  591. {
  592. name = "Round Complete",
  593. length = 35,
  594. displaylength = 5
  595. }
  596. }
  597. q.playerlist = {}
  598. q.maxplayers = maxplayers
  599. q.buildzone = buildzone
  600.  
  601. return q
  602. end
  603.  
  604.  
  605. --creates a ring of blocks using coordinates
  606. function fillRing(x,y,z,w,block)
  607. commands.fill(x,y,z,x+w,y,z,block)
  608. commands.fill(x+w,y,z,x+w,y,z+w,block)
  609. commands.fill(x,y,z+w,x+w,y,z+w,block)
  610. commands.fill(x,y,z+w,x,y,z,block)
  611. end
  612.  
  613. function setup()
  614. local game = {}
  615. game.vocab = {}
  616. game.builds = {}
  617. game.queues = {}
  618. game.waitlist = {}
  619. game.spawn = SPAWN
  620. game.lastClock = os.clock()
  621. game.nowTime = os.clock()
  622.  
  623. --kill all villagers
  624. commands.exec("kill @e[type=Villager]")
  625.  
  626. --buildzone and vocabzone creation
  627. game.vocab = makeVocabZones(NUMBER_OF_VOCAB,VOCAB_WIDTH)
  628.  
  629. game.builds = makeBuildzones(NUMBER_OF_BUILDZONES,game.vocab,BUILDZONE_WIDTH,BUILDZONE_FLOOR_HEIGHT)
  630.  
  631. for i,build in ipairs(game.builds) do
  632. table.insert(game.queues,newQueue(build,4))
  633. end
  634.  
  635. for i,vz in ipairs(game.vocab) do
  636. local x,y,z,w = vz.x,vz.y,vz.z,vz.w
  637. local cx,cy,cz = vz.cx,vz.cy,vz.cz
  638.  
  639. local detector, message1 = commands.testforblock(x+(math.floor(w/2)),y,z+(math.floor(w/2)),BLOCKS.DETECT.block)
  640. local blocker, message2 = commands.testforblock(x+(math.floor(w/2)),y,z+(math.floor(w/2)),BLOCKS.DETECT_DEAD.block)
  641. if not (detector or blocker) then
  642. for nx=0,2 do
  643. for nz=0,2 do
  644. commands.setblock(x+(nx*9)+4,y-1,z+(nz*9)+4,BLOCKS.VOCAB_REPLACE.block)
  645. commands.setblock(cx+(nx*9)+4,cy-1,cz+(nz*9)+4,BLOCKS.VOCAB_DETECT.block)
  646. end
  647. end
  648. commands.setblock(x+(math.floor(w/2)),y,z+(math.floor(w/2)),BLOCKS.DETECT_DEAD.block)
  649.  
  650. end
  651.  
  652. end
  653.  
  654. for i, name in ipairs(VOCAB_NAMES) do
  655. commands.scoreboard("objectives","add",name,"dummy")
  656. end
  657.  
  658. commands.gamerule("doDaylightCycle",false)
  659. commands.gamerule("keepInventory",true)
  660. commands.gamerule("doTileDrops",false)
  661. commands.gamerule("logAdminCommands",false)
  662. commands.gamerule("commandBlockOutput",false)
  663. commands.time("set",6000)
  664. commands.scoreboard("objectives","add","highscores","dummy","Server-wide Best")
  665. commands.scoreboard("objectives","add","VillagerLife","dummy")
  666. commands.scoreboard("objectives","add","built","dummy", "Structures Built")
  667. commands.scoreboard("objectives","add","highest","dummy", "Personal Highest")
  668. commands.scoreboard("objectives","add","played","dummy","Games Played")
  669.  
  670. commands.title("@a","times",0,30,30)
  671. math.randomseed( os.time() )
  672. commands.scoreboard("objectives","setdisplay","sidebar","highscores")
  673. commands.scoreboard("objectives","setdisplay","list","played")
  674.  
  675. if DEBUG_MODE then
  676. for i,build in ipairs(game.builds) do
  677. build.phase = 2
  678. build.timer = 500
  679. end
  680. end
  681.  
  682. print("Computer Co-ordinates ",ox,oy,oz)
  683. print("20,000 Blocks Active!")
  684.  
  685. return game
  686. end
  687.  
  688. function checkForSquids(game)
  689. --execute on all squids
  690. local squidders = getSquids()
  691. dealWithSquidders(game,squidders)
  692. end
  693.  
  694. --main game loop
  695. --runs the game object through each of these update steps in order
  696. function update(game)
  697. local elapsed = updateClock(game)
  698. --update players
  699. checkPlayers(game)
  700. doTimerUpdates(game,elapsed)
  701. doPhaseUpdates(game)
  702. doPhaseEnds(game)
  703. checkBoundaries(game)
  704. checkForSquids(game)
  705. if #game.waitlist > 0 then allocateWaiters(game) end
  706. end
  707.  
  708. --calculates elapsed time during a game tick
  709. function updateClock(game)
  710. game.nowTime = os.clock()
  711. local elapsed = game.nowTime - game.lastClock
  712. game.lastClock = game.nowTime
  713. return elapsed
  714. end
  715.  
  716. --updates all kews in the game object based on elapsed time
  717. function doTimerUpdates(game,elapsed)
  718. for i,kew in ipairs(game.queues) do
  719. kew.timer = kew.timer - elapsed
  720. end
  721. end
  722.  
  723. --check players are inside their buildzone and move them back if not
  724. function checkBoundaries(game)
  725. for i,kew in ipairs(game.queues) do
  726. if kew.phase ==2 then
  727. --boundaries
  728. local x_min = kew.buildzone.x
  729. local x_max = kew.buildzone.x+kew.buildzone.w
  730. local z_min = kew.buildzone.z
  731. local z_max = kew.buildzone.z+kew.buildzone.w
  732.  
  733. local toBeCorrected = {}
  734.  
  735. for j,player in ipairs(kew.playerlist) do
  736. local listOfOne = getAllPos('m=2,name='..player.name)
  737. if listOfOne and listOfOne[1] then
  738. player.x = listOfOne[1].x
  739. player.y = listOfOne[1].y
  740. player.z = listOfOne[1].z
  741. local changed = false
  742. if player.x > x_max then
  743. changed = true
  744. player.x = x_max-2
  745. end
  746. if player.x < x_min then
  747. changed = true
  748. player.x = x_min+2
  749. end
  750. if player.z > z_max then
  751. changed = true
  752. player.z = z_max-2
  753. end
  754. if player.z < z_min then
  755. changed = true
  756. player.z = z_min+2
  757. end
  758. if changed then teleportToPoint(player.x,kew.buildzone.y,player.z,{player},false,"TELEPORTED: Please stay inside the building zone until your game has ended") end
  759. end
  760. end
  761. end
  762. end
  763. end
  764.  
  765.  
  766. --here you can set the logic which determines if a buildzone was valuable.
  767. --Return true if it is crap and should be replaced
  768. function checkIfBuildzoneIsCrap(buildzone)
  769. if #buildzone.structures < 5 then
  770. print("Buildzone was crap")
  771. return true
  772. end
  773. print("Buildzone was ok")
  774. return false
  775. end
  776.  
  777.  
  778. --Everything that happens after a buildzone was completed
  779. --due to time limit.
  780. function cleanAfterVictory(buildzone)
  781. commands.async.setblock(buildzone.x,buildzone.y,buildzone.z,BLOCKS.VICTORY_MARKER.block)
  782. fillRing(buildzone.x,buildzone.y,buildzone.z,buildzone.w,"minecraft:air",0,"replace",BLOCKS.CONSTRUCTION.block,BLOCKS.CONSTRUCTION.data)
  783. for h=0,VICTORY_HEIGHT do
  784. commands.async.fill(buildzone.x,buildzone.y+h,buildzone.z,buildzone.x+buildzone.w,buildzone.y+h,buildzone.z+buildzone.w,"minecraft:air 0","replace",BLOCKS.DETECT.block,BLOCKS.DETECT.data)
  785. commands.async.fill(buildzone.x,buildzone.y+h,buildzone.z,buildzone.x+buildzone.w,buildzone.y+h,buildzone.z+buildzone.w,"minecraft:air 0","replace",BLOCKS.PLUG.block,BLOCKS.PLUG.data)
  786. commands.async.fill(buildzone.x,buildzone.y+h,buildzone.z,buildzone.x+buildzone.w,buildzone.y+h,buildzone.z+buildzone.w,"minecraft:air 0","replace",BLOCKS.BUILDING_GARDEN.block,BLOCKS.BUILDING_GARDEN.data)
  787. commands.async.fill(buildzone.x,buildzone.y+h,buildzone.z,buildzone.x+buildzone.w,buildzone.y+h,buildzone.z+buildzone.w,"minecraft:air 0","replace",BLOCKS.BUILDING_HOUSE.block,BLOCKS.BUILDING_HOUSE.data)
  788. end
  789. commands.async.fill(buildzone.x,buildzone.y-1,buildzone.z,buildzone.x+buildzone.w,buildzone.y-1,buildzone.z+buildzone.w,BLOCKS.CAMP_FLOOR.block,BLOCKS.CAMP_FLOOR.data,"replace",BLOCKS.PLUG.block,BLOCKS.PLUG.data)
  790. commands.async.fill(buildzone.x,buildzone.y,buildzone.z,buildzone.x+buildzone.w,buildzone.y,buildzone.z+buildzone.w,BLOCKS.PHVFLOOR.block,BLOCKS.PHVFLOOR.data,"replace","minecraft:air","0")
  791.  
  792. local wasCrap = checkIfBuildzoneIsCrap(buildzone)
  793. if wasCrap then
  794. --mark this buildzone for replacement
  795. commands.async.setblock(buildzone.x,buildzone.y,buildzone.z,"minecraft:air")
  796. end
  797. end
  798.  
  799. --these happen every tick and require the game object
  800. --updates are performed on each Queue (kew) and within each
  801. --of those on each buildzone.
  802. function doPhaseUpdates(game)
  803. for i,kew in ipairs(game.queues) do
  804.  
  805. local minutes = string.format("%02d",math.floor(kew.timer/60))
  806. local seconds = string.format("%02d",math.floor(kew.timer - (minutes*60)))
  807. if kew.timer <= 0 then
  808. minutes = "00"
  809. seconds = "00"
  810. end
  811.  
  812. if kew.phase == 1 then
  813. --waiting phase
  814. if #kew.playerlist == kew.maxplayers and kew.timer > 5 then kew.timer = 5 end
  815. if not DEBUG_MODE and #kew.playerlist == 0 then kew.timer = kew.phases[1].length end
  816.  
  817. displayTitleToGroup(kew.playerlist,"Game starting!")
  818. displayTimeToGroup(kew.playerlist,minutes,seconds)
  819. --show countdown
  820. elseif kew.phase == 2 then
  821. --playing phase
  822. if #kew.playerlist == 0 then timer = 0 end -- finish if all players quit
  823. local victory = updatePlayedZone(kew.buildzone) -- do vocab logic
  824. displayTimeToGroup(kew.playerlist,minutes,seconds)
  825.  
  826. elseif kew.phase == 3 then
  827. --end phase
  828. displayTitleToGroup(kew.playerlist,"Return with Heimkehrer")
  829. displayTimeToGroup(kew.playerlist,minutes,seconds)
  830.  
  831.  
  832. end
  833. end
  834. end
  835.  
  836. --this runs after a buildzone is completed
  837. --it should tally structure types and set scoreboard highscores
  838. --it also rewards all participants with more played score
  839. function processHighscores(kew)
  840. local buildzone = kew.buildzone
  841. --calculate total structures
  842. local structures = tracker.tallyTable(buildzone.structures)
  843. local most = tracker.getScore("Most-Structures","highscores")
  844. if #buildzone.structures > most.count then
  845. commands.async.scoreboard("players","set","Most-Structures","highscores",#buildzone.structures)
  846. commands.async.say("@a","The record for Most Structures in a single game has been topped!")
  847. end
  848. --calculate total residential structures
  849. --calculate total commerical structures
  850. --calculate total industrial structures
  851. --calculate highest placement
  852. local highest = tracker.getScore("Highest-Structure","highscores")
  853. if buildzone.highest - buildzone.y >= highest.count then
  854. commands.async.scoreboard("players","set","Highest-Structure","highscores",buildzone.highest - buildzone.y)
  855. commands.async.say("@a","The record for the Highest Structure in a single game as been topped!")
  856. end
  857.  
  858. --add score to players who finished this game
  859. for _,player in ipairs(kew.playerlist) do
  860. commands.async.scoreboard("players","add",player.name,"played",1)
  861. end
  862. end
  863.  
  864. --function to export a buildzone detail once it is complete
  865. --requires a kew so it can access the playerlist
  866. local function exportKewData(kew)
  867. local buildzone = kew.buildzone
  868. local saved = {}
  869. saved.position =
  870. {
  871. x=buildzone.x,
  872. y=buildzone.y,
  873. z=buildzone.z
  874. }
  875. saved.completed = os.time()
  876. saved.players = {}
  877. for _, player in ipairs(kew.playerlist) do
  878. table.insert(saved.players,player.name)
  879. end
  880. saved.structures = buildzone.structures
  881. saved.totals = tracker.tallyTable(buildzone.structures)
  882. saved.highest = buildzone.highest - buildzone.y
  883.  
  884. fs.makeDir("/records")
  885. local file = fs.open("/records/"..buildzone.x.."_"..buildzone.z,"w")
  886. file.write(json.encodePretty(saved))
  887. file.close()
  888. end
  889.  
  890. --this code runs ONCE at the end of each phase
  891. --what actually happens is specific to which phase the
  892. --particular kew is in.
  893. function doPhaseEnds(game)
  894. for i,kew in ipairs(game.queues) do
  895. if kew.timer <= 0 then
  896. if kew.phase == 1 then
  897. --waiting phase ends goto play phase
  898.  
  899. moveBuildzone(kew.buildzone,game.builds)
  900. teleportToZone(kew.buildzone,kew.playerlist,"TELEPORTED: Your game has started.")--teleport selected players
  901. cleanBuildzone(kew.buildzone)
  902. prepareBuildzone(kew.buildzone)--prepare build zone
  903. giveItems(kew.playerlist,STARTING_ITEMS) --give starting items
  904. displayTitle(kew.buildzone.selector,"Build!")
  905. kew.victory = false
  906. displayTime(kew.buildzone.selector,0,0)
  907. kew.phase = 2
  908. kew.timer = kew.phases[2].length
  909. elseif kew.phase == 2 then
  910. --playing phase ends goto end phase
  911. processHighscores(kew)
  912. exportKewData(kew)
  913. cleanAfterVictory(kew.buildzone)
  914. kew.phase = 3
  915. displayTime(kew.buildzone.selector,0,0)
  916. kew.timer = kew.phases[3].length
  917. elseif kew.phase == 3 then
  918. --end phase ends goto waiting phase
  919. removePlayersFromKew(game,kew)
  920. kew.phase = 1
  921. displayTime(kew.buildzone.selector,0,0)
  922. kew.timer = kew.phases[1].length
  923. end
  924. end
  925. end
  926. end
  927.  
  928.  
  929. --Replaces everything that is needed to start the game. Does not rebuild the floor, or clear anything away.
  930. --based on the settings it creates a full grid, or a partial grid, or no grid
  931. --it also places the ring, although this is disabled for now
  932. function prepareBuildzone(buildzone)
  933. local bz = buildzone
  934. local x,y,z,w = bz.x,bz.y,bz.z,bz.w
  935. --commands.fill(x,y-1,z,x+w,y-1,z+w,BLOCKS.CAMP_FLOOR)
  936. fillRing(buildzone.x,buildzone.y,buildzone.z,buildzone.w,BLOCKS.CONSTRUCTION.block)
  937. if DO_GRID then
  938. for x=0,6 do
  939. for z=0,6 do
  940. local rand = math.random()*100
  941. --local result, text = commands.testforblock(bz.x+(x*9)+4,bz.y-1,bz.z+(z*9)+4,BLOCKS.CAMP_FLOOR.block)
  942. if rand > GRID_HOLE_CHANCE then --and result then
  943. commands.async.setblock(bz.x+(x*9)+4,bz.y,bz.z+(z*9)+4,BLOCKS.DETECT.block,BLOCKS.DETECT.data,"replace","minecraft:air")
  944. commands.async.fill(bz.x+(x*9)+1,bz.y-1,bz.z+(z*9)+4,bz.x+(x*9)+7,bz.y-1,bz.z+(z*9)+4,BLOCKS.PLUG.block)
  945. commands.async.fill(bz.x+(x*9)+4,bz.y-1,bz.z+(z*9)+1,bz.x+(x*9)+4,bz.y-1,bz.z+(z*9)+7,BLOCKS.PLUG.block)
  946. --commands.async.setblock(bz.x+(x*9)+4,bz.y-1,bz.z+(z*9)+4,BLOCKS.CAMP_FLOOR.block)
  947. end
  948. end
  949. end
  950. end
  951. commands.async.setblock(buildzone.x,buildzone.y,buildzone.z,BLOCKS.CONSTRUCTION.block)
  952. end
  953.  
  954. --deletes everything inside the buildzone
  955. function cleanBuildzone(buildzone)
  956. print("Cleaning buildzone")
  957. for h=0,VICTORY_HEIGHT+20 do
  958. commands.async.fill(buildzone.x,buildzone.y+h,buildzone.z,buildzone.x+buildzone.w,buildzone.y+h,buildzone.z+buildzone.w,"minecraft:air")
  959. end
  960. end
  961.  
  962. --moves all players assigned to the queue into the waiting area for the provided game.
  963. --It also changes them to Adventure mode and clears their inventory
  964. function respawnPlayers(game,kew)
  965. teleportToPoint(game.spawn.x,game.spawn.y,game.spawn.z,kew.playerlist,true,"TELEPORTED: Your game ended so you have been returned to the Spawn Point") --put players back in spawn area
  966. for i,player in ipairs(kew.playerlist) do
  967. --table.insert(game.waitlist,player)
  968. respawnPlayer(player,"")
  969. end
  970. kew.playerlist = {}
  971. end
  972.  
  973. function removePlayersFromKew(game,kew)
  974. for _, player in ipairs(kew.playerlist) do
  975. commands.tell(player.name,"Your game is over. Use your Heimkehrer to return to spawn")
  976. end
  977. kew.playerlist = {}
  978. end
  979.  
  980. function respawnPlayer(playername,message)
  981. commands.tell(playername,message)
  982. commands.async.gamemode(2,playername)
  983. commands.async.clear(playername,"minecraft:wool")
  984. commands.async.clear(playername,"minecraft:stone_pickaxe")
  985. end
  986.  
  987. function checkForPlayerInBuildzone(player,buildzone)
  988. local result,message = commands.testfor('@a[name='..player.name..','..buildzone.selector..']')
  989. return result
  990. end
  991.  
  992. function checkForPlayerInWaitzone(player)
  993. local selector = "x="..WAITZONE.x..",y="..WAITZONE.y..",z="..WAITZONE.z..",dx="..WAITZONE.w..",dy=256,dz="..WAITZONE.l
  994. local result,message = commands.testfor('@a[name='..player.name..','..selector..']')
  995. return result
  996. end
  997.  
  998. function checkPlayers(game)
  999. local selector = "x="..WAITZONE.x..",y="..WAITZONE.y..",z="..WAITZONE.z..",dx="..WAITZONE.w..",dy=256,dz="..WAITZONE.l
  1000. local loggedIn = getAllPos('m=2,'..selector)
  1001. --refresh waitlist
  1002. game.waitlist = loggedIn
  1003. --check currently playing players
  1004. for l,kew in ipairs(game.queues) do
  1005. for i,builder in ipairs(kew.playerlist) do
  1006. local isPlaying = checkForPlayerInBuildzone(builder,kew.buildzone)
  1007. --remove players who are already in kews from the waitlist
  1008. for j, player in ipairs(loggedIn) do
  1009. if player.name == builder.name then
  1010. table.remove(loggedIn,j)
  1011. end
  1012. end
  1013. --if the game is in progress and the player is not found then remove them from the gamekew
  1014. if not isPlaying and kew.phase == 2 then
  1015. --table.remove(kew.playerlist,i)
  1016. --print("Removed "..builder.name.." from game in progress")
  1017. end
  1018. end
  1019. end
  1020. end
  1021.  
  1022. --adds players who wait in the orange room to slots in waiting buildzones
  1023. function allocateWaiters(game)
  1024. --find free slots
  1025. local freeslots = {}
  1026. for i, kew in ipairs(game.queues) do
  1027. if kew.phase == 1 and #kew.playerlist < kew.maxplayers then
  1028. local slots = kew.maxplayers - #kew.playerlist
  1029. for j=1,slots do
  1030. table.insert(freeslots,kew)
  1031. end
  1032. end
  1033. end
  1034.  
  1035. --RE-ENABLE SECOND SHUFFLETABLE IF YOU WANT RANDOM PLAYER MATCHUPS
  1036. shuffleTable(game.waitlist)
  1037. --shuffleTable(freeslots)
  1038.  
  1039. while #freeslots > 0 and #game.waitlist > 0 do
  1040. local player = table.remove(game.waitlist,1)
  1041. local freeslot = table.remove(freeslots,1).playerlist
  1042. table.insert(freeslot,player)
  1043. end
  1044. end
  1045.  
  1046. --PARTICLE FUNCTIONS
  1047. function searchParticle(x,y,z)
  1048. commands.async.particle("fireworksSpark",x,y,z,0.01,3,0.01,0.01,100)
  1049. end
  1050.  
  1051. function successParticle(x,y,z)
  1052. commands.async.particle("happyVillager",x,y,z,2,2,2,1,1000)
  1053. commands.async.playsound("random.levelup","@a",x,y,z,1,1.2)
  1054. end
  1055.  
  1056. function failParticle(x,y,z)
  1057. commands.async.particle("reddust",x,y,z,0.1,0.1,1.5,1,200)
  1058. commands.async.particle("reddust",x,y,z,1.5,0.1,0.1,1,200)
  1059. commands.async.playsound("random.bowhit","@a",x,y,z,1,0.8)
  1060. end
  1061.  
  1062. --makes sure that incoming check requests dont exist already
  1063. function addToChecklist(player,buildzone)
  1064. for _, detector in ipairs(buildzone.waitingForCheck) do
  1065. if detector.x == player.x and detector.y == player.y and detector.z == player.z then
  1066. return false
  1067. end
  1068. end
  1069. table.insert(buildzone.waitingForCheck,player)
  1070. return true
  1071. end
  1072.  
  1073. --removed all barrier blocks from a buildzone which are used to carve space in vocabs
  1074. function cleanBarriers(buildzone)
  1075. for h=0,50 do
  1076. commands.async.fill(buildzone.x,buildzone.y+h,buildzone.z,buildzone.x+buildzone.w,buildzone.y+h,buildzone.z+buildzone.w,"minecraft:air",0,"replace","minecraft:barrier")
  1077. end
  1078. end
  1079.  
  1080. --The main chunk of code which deals with stepping on detector blocks and reading the vocab
  1081. function updatePlayedZone(buildzone)
  1082. local victory = false
  1083. local buildzoneSelector = buildzone.selector
  1084. --get all players on diamond, add them to the list of things to check
  1085. local detectLocations = getAllOnBlockType(BLOCKS.DETECT.block,buildzoneSelector)
  1086. for _, player in ipairs(detectLocations) do
  1087. addToChecklist(player,buildzone)
  1088. end
  1089.  
  1090. --DEAL WITH THE DETECTOR AT THE TOP OF THE LIST IF THERE IS ONE
  1091. if #buildzone.waitingForCheck > 0 then
  1092. --DO PARTICLE EFFECTS IF A DETECTING BLOCK THAT IS DETECTING
  1093. for i,loc in ipairs(buildzone.waitingForCheck) do
  1094. searchParticle(loc.x,loc.y+1,loc.z)
  1095. end
  1096. local totalResult = false
  1097. local checked = table.remove(buildzone.waitingForCheck,1)
  1098. local x,y,z,name = checked.x,checked.y,checked.z,checked.name
  1099. for i,vocab in pairs(buildzone.vocab) do
  1100. local result,message = commands.testforblocks(vocab.x,vocab.y,vocab.z,vocab.x+vocab.w,vocab.y+VOCAB_HEIGHT,vocab.z+vocab.w,x-math.floor(vocab.w/2),y-1,z-math.floor(vocab.w/2),"masked")
  1101. if result then
  1102. --clone in the correct vocab
  1103. local cloneres,clonemes = commands.clone(vocab.cx,vocab.cy,vocab.cz,vocab.cx+vocab.w,vocab.cy+VOCAB_HEIGHT,vocab.cz+vocab.w,x-math.floor(vocab.w/2),y-1,z-math.floor(vocab.w/2),"masked")
  1104. if DEBUG_MODE then
  1105. print(clonemes[1])
  1106. end
  1107. commands.async.give(name,vocab.reward)
  1108. commands.async.tellraw(name,'["",{"text":"You built a '..vocab.name.. ' and received more building materials!!","color":"green"}]')
  1109.  
  1110. --clear out barrier blocks
  1111. cleanBarriers(buildzone)
  1112.  
  1113. --add the new structure to the records and check if it is the highest
  1114. table.insert(buildzone.structures,vocab.name)
  1115. if y > buildzone.highest then
  1116. buildzone.highest = y
  1117. local personalbest = tracker.getScore(name,"highest")
  1118. if personalbest.count < y - buildzone.y then
  1119. commands.async.tell(name,"You just topped your personal record for highest structure")
  1120. commands.async.scoreboard("players","add",name,"highest",1)
  1121. end
  1122. end
  1123.  
  1124. --increase score for the building player
  1125. commands.async.scoreboard("players","add",name,"built",1)
  1126. commands.async.scoreboard("players","add",name,vocab.name,1)
  1127.  
  1128. totalResult = true
  1129. break
  1130.  
  1131. end
  1132. end
  1133. if totalResult then
  1134. --yey win, do a happy time
  1135. successParticle(x,y,z)
  1136. else
  1137. --no vocab found so do a fail particle
  1138. commands.async.tellraw(name,'["",{"text":"Your structure is not built correctly, try a different shape.","color":"red"}]')
  1139. failParticle(x,y-1,z)
  1140. end
  1141. end
  1142. return victory
  1143. end
  1144.  
  1145. --Display game information on the monitor
  1146. function debugDisplay(game)
  1147. monitor.clear()
  1148. if blink then
  1149. monitor.setCursorPos(1,1)
  1150. monitor.setTextColor(colors.red)
  1151. monitor.write("Running")
  1152. monitor.setTextColor(colors.white)
  1153. redstone.setOutput("top",true)
  1154. blink = false
  1155. else
  1156. redstone.setOutput("top",false)
  1157. blink = true
  1158. end
  1159. local line = 2
  1160.  
  1161. for i,kew in ipairs(game.queues) do
  1162. monitor.setCursorPos(1,line)
  1163. local minutes = string.format("%02d",math.floor(kew.timer/60))
  1164. local seconds = string.format("%02d",math.floor(kew.timer - (minutes*60)))
  1165. monitor.write("Buildzone "..i.." | Phase: "..kew.phase.." | Time: "..minutes..":"..seconds)
  1166. monitor.setCursorPos(1,line+1)
  1167. for i,player in ipairs(kew.playerlist) do
  1168. monitor.write(player.name.." ")
  1169. end
  1170. line = line +2
  1171. end
  1172.  
  1173. monitor.setCursorPos(1,10)
  1174. for i,player in ipairs(game.waitlist) do
  1175. monitor.write(player.name.." ")
  1176. end
  1177.  
  1178. end
  1179.  
  1180. --BEGIN RUNTIME CODE
  1181. local blink = true
  1182. local game = setup()
  1183. while true do
  1184. update(game)
  1185. if monitor then debugDisplay(game) end
  1186. commands.async.weather("clear",10000)
  1187.  
  1188. local resetbutton = redstone.getInput("left")
  1189. if resetbutton then
  1190. print("reset!")
  1191. for i,kew in ipairs(game.queues) do
  1192. if kew.phase == 2 then
  1193. kew.timer = 5
  1194. end
  1195. end
  1196. end
  1197. sleep(2)
  1198. end
Advertisement
Add Comment
Please, Sign In to add comment