Advertisement
antonsavov

Untitled

Mar 9th, 2017
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.89 KB | None | 0 0
  1. local VERSION = '1.0.0 - Public Release'
  2.  
  3. print("Starting 20.000 Blocks Tutorial")
  4.  
  5. commands.scoreboard("objectives","add","tut_state","dummy")
  6.  
  7. DEBUG_MODE = false
  8. local ox,oy,oz = commands.getBlockPosition()
  9.  
  10. NUMBER_OF_TUT_ZONES = 3
  11. WALL_THICKNESS = 2 -- the thickness of the walls between the tutorial zones
  12. REFRESH_ZONE = {
  13. x=12317,
  14. y=55,
  15. z=-1796,
  16. w=17,
  17. l=59,
  18. h=12
  19. }
  20. INCOMING_ZONE = {
  21. x=12370,
  22. y=69,
  23. z=-1716,
  24. w=3,
  25. l=3,
  26. h=3
  27. }
  28. OUTGOING_POINT = {
  29. x=12314,
  30. y=56,
  31. z=-1774,
  32. a=90,
  33. b=0
  34. }
  35. START_POINT_OFFSET = { --this is the offset of starting point for each tutorial zone from the zone's origin
  36. x=64,
  37. y=1,
  38. z=14
  39. }
  40.  
  41. WELCOME_AREA = {
  42. x=12477,
  43. y=87,
  44. z=-1826,
  45. r1=0,
  46. r2=0
  47. }
  48. PLAY_AREA = {
  49. x=12113,
  50. y=57,
  51. z=-1777,
  52. r1=90,
  53. r2=0
  54. }
  55. TUT_WAIT_AREA = {
  56. x=12381,
  57. y=69,
  58. z=-1716,
  59. r1=115,
  60. r2=0
  61. }
  62. TUT_TIMEOUT_SECONDS = 600
  63. NUMBER_OF_VOCAB = 10
  64. VOCAB_LOCATION = {
  65. x=0,
  66. y=57,
  67. z=5
  68. }
  69. VOCAB_WIDTH = 27
  70. VOCAB_HEIGHT = 19
  71. TUTORIAL_VOCABS = {1,2,3,4,9,10,11,12,37,38,39,40,25,26,27,28}
  72.  
  73.  
  74. BLOCKS = {
  75. CAMP_FLOOR = {block='minecraft:sandstone',data=0},
  76. CONSTRUCTION = {block='minecraft:diamond_ore',data=0},
  77. RING = {block='minecraft:diamond_ore',data=0},
  78. DETECT = {block='minecraft:red_sandstone',data=0},
  79. DETECT_DEAD = {block='minecraft:obsidian',data=0},
  80. VOCAB_DETECT = {block="minecraft:quartz_block",data=0},
  81. VOCAB_REPLACE = {block="minecraft:coal_block",data=0},
  82. VICTORY_MARKER = {block="minecraft:emerald_block",data=0},
  83. PLUG = {block="minecraft:lapis_ore",data=0},
  84. PHVFLOOR = {block="minecraft:stone_slab",data=3},
  85. BUILDING_HOUSE = {block="minecraft:wool",data=0},
  86. BUILDING_GARDEN = {block="minecraft:wool",data=13},
  87. BUILDING_WATER = {block="minecraft:wool",data=1},
  88. }
  89.  
  90.  
  91. --call these to return a proper minecraft item string including adventure mode properties
  92. function houseBlock(quant)
  93. 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..'"]}'
  94. return text
  95. end
  96.  
  97. function gardenBlock(quant)
  98. 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..'"]}'
  99. return text
  100. end
  101.  
  102.  
  103.  
  104. PICKAXE_USES = 40
  105. pickaxe = 'stone_pickaxe 1 '..131-PICKAXE_USES..' {CanDestroy:["'..BLOCKS.BUILDING_HOUSE.block..'"],display:{Name:"Resource Remover",Lore:[Use the pickaxe to remove up to '..PICKAXE_USES..' resource blocks]}}'
  106.  
  107.  
  108. STARTING_ITEMS = {
  109. houseBlock(10), gardenBlock(10),pickaxe
  110. }
  111.  
  112. REWARDS = {}
  113.  
  114. DEFAULT_NAME = 'default-vocab'
  115.  
  116. VOCABS_DATA = {
  117. -- urban houses
  118. {id=1, column=1, row=1,nameEN="SINGLE-FAMILY-HOUSE",nameDE="EINFAMILIENHAUS", typeEN="HOUSES",typeDE="HÄUSER",height=10, slots=2, green=false, greenSlots=0, rewardUrban=false, rewardCount=4},
  119. {id=2, column=1, row=2,nameEN="SINGLE-FAMILY-HOUSE",nameDE="EINFAMILIENHAUS", typeEN="HOUSES",typeDE="HÄUSER",height=10, slots=2, green=false, greenSlots=0, rewardUrban=false, rewardCount=4},
  120. {id=3, column=1, row=3,nameEN="SINGLE-FAMILY-HOUSE",nameDE="EINFAMILIENHAUS", typeEN="HOUSES",typeDE="HÄUSER",height=10, slots=2, green=false, greenSlots=0, rewardUrban=false, rewardCount=4},
  121. {id=4, column=1, row=4,nameEN="SINGLE-FAMILY-HOUSE",nameDE="EINFAMILIENHAUS", typeEN="HOUSES",typeDE="HÄUSER",height=10, slots=2, green=false, greenSlots=0, rewardUrban=false, rewardCount=4},
  122. -- urban businesses
  123. {id=5, column=2, row=1,nameEN="GYM",nameDE="FITNESSSTUDIO", typeEN="BUSINESSES",typeDE="GESCHÄFTE",height=20, slots=5, green=false, greenSlots=0, rewardUrban=false, rewardCount=8},
  124. {id=6, column=2, row=2,nameEN="OFFICE-BUILDING",nameDE="BÜROGEBÄUDE", typeEN="BUSINESSES",typeDE="GESCHÄFTE",height=20, slots=5, green=false, greenSlots=0, rewardUrban=false, rewardCount=8},
  125. {id=7, column=2, row=3,nameEN="HOTEL",nameDE="HOTEL", typeEN="BUSINESSES",typeDE="GESCHÄFTE",height=20, slots=5, green=false, greenSlots=0, rewardUrban=false, rewardCount=8},
  126. {id=8, column=2, row=4 ,nameEN="BANK",nameDE="BANK", typeEN="BUSINESSES",typeDE="GESCHÄFTE",height=20, slots=5, green=false, greenSlots=0, rewardUrban=false, rewardCount=8},
  127. -- urban tech&science spaces
  128. {id=9, column=3, row=1,nameEN="LIBRARY",nameDE="BIBLIOTHEK", typeEN="TECH & SCIENCE SPACES",typeDE="WISSENSCHAFTSGEBÄUDE",height=16, slots=1, green=false, greenSlots=0, rewardUrban=false, rewardCount=10},
  129. {id=10, column=3, row=2,nameEN="FABLAB",nameDE="INNOVATIONSZENTRUM", typeEN="TECH & SCIENCE SPACES",typeDE="WISSENSCHAFTSGEBÄUDE",height=16, slots=1, green=false, greenSlots=0, rewardUrban=false, rewardCount=10},
  130. -- green tech&science spaces
  131. {id=11, column=3, row=3,nameEN="AQUAPONIC-GREENHOUSE",nameDE="AQUAPONIK-GEWÄCHSHAUS", typeEN="TECH & SCIENCE SPACES",typeDE="WISSENSCHAFTSGEBÄUDE",height=16, slots=1, green=true, greenSlots=1, rewardUrban=true, rewardCount=10},
  132. {id=12, column=3, row=4,nameEN="SCIENCE-BRIDGE",nameDE="WISSENSCHAFTSBRÜCKE", typeEN="TECH & SCIENCE SPACES",typeDE="WISSENSCHAFTSGEBÄUDE",height=16, slots=1, green=true, greenSlots=1, rewardUrban=true, rewardCount=10},
  133. -- urban house extensions
  134. {id=13, column=4, row=1,nameEN="HOUSE-EXTENSION",nameDE="HAUSERWEITERUNG", typeEN="EXTENSIONS",typeDE="ERWEITERUNGEN",height=10, slots=1, green=false, greenSlots=0, rewardUrban=false, rewardCount=6},
  135. {id=14, column=4, row=2,nameEN="HOUSE-EXTENSION",nameDE="HAUSERWEITERUNG", typeEN="EXTENSIONS",typeDE="ERWEITERUNGEN",height=10, slots=1, green=false, greenSlots=0, rewardUrban=false, rewardCount=6},
  136. {id=15, column=4, row=3,nameEN="HOUSE-EXTENSION",nameDE="HAUSERWEITERUNG", typeEN="EXTENSIONS",typeDE="ERWEITERUNGEN",height=10, slots=1, green=false, greenSlots=0, rewardUrban=false, rewardCount=6},
  137. {id=16, column=4, row=4,nameEN="HOUSE-EXTENSION",nameDE="HAUSERWEITERUNG", typeEN="EXTENSIONS",typeDE="ERWEITERUNGEN",height=10, slots=1, green=false, greenSlots=0, rewardUrban=false, rewardCount=6},
  138. --risers
  139. {id=17, column=5, row=1,nameEN="DOUBLE-FLOOR-RISER",nameDE="VERSCHIEBUNG-ZWEI-HOCH", typeEN="RISERS",typeDE="VERTIKALE VERSCHIEBUNGEN",height=0, slots=0, green=false, greenSlots=0, rewardUrban=true, rewardCount=8},
  140. {id=18, column=5, row=2,nameEN="SINGLE-FLOOR-RISER",nameDE="VERSCHIEBUNG-EINEN-HOCH", typeEN="RISERS",typeDE="VERTIKALE VERSCHIEBUNGEN",height=0, slots=0, green=false, greenSlots=0, rewardUrban=true, rewardCount=6},
  141. --plazas
  142. {id=19, column=5, row=3,nameEN="CITY-PLAZA",nameDE="STÄDTISCHER PLATZ", typeEN="PLAZAS",typeDE="PLÄTZE",height=0, slots=0, green=false, greenSlots=0, rewardUrban=false, rewardCount=2},
  143. {id=20, column=5, row=4,nameEN="PARK-PLAZA",nameDE="GRÜNER PLATZ", typeEN="PLAZAS",typeDE="PLÄTZE",height=0, slots=0, green=true, greenSlots=1, rewardUrban=true, rewardCount=2},
  144. --green businesses
  145. {id=21, column=6, row=1,nameEN="GREEN-GYM",nameDE="GRÜNES FITNESSSTUDIO", typeEN="BUSINESSES",typeDE="GESCHÄFTE",height=20, slots=5, green=true, greenSlots=5, rewardUrban=true, rewardCount=8},
  146. {id=22, column=6, row=2,nameEN="GREEN-OFFICE-BUILDING",nameDE="GRÜNES BÜROGEBÄUDE", typeEN="BUSINESSES",typeDE="GESCHÄFTE",height=20, slots=5, green=true, greenSlots=5, rewardUrban=true, rewardCount=8},
  147. {id=23, column=6, row=3,nameEN="GREEN-HOTEL",nameDE="GRÜNES HOTEL", typeEN="BUSINESSES",typeDE="GESCHÄFTE",height=20, slots=5, green=true, greenSlots=5, rewardUrban=true, rewardCount=8},
  148. {id=24, column=6, row=4,nameEN="GREEN-BANK",nameDE="GRÜNES BANK", typeEN="BUSINESSES",typeDE="GESCHÄFTE",height=20, slots=5, green=true, greenSlots=5, rewardUrban=true, rewardCount=8},
  149. ---green private garden extensions
  150. {id=25, column=7, row=1,nameEN="HOUSE-GARDEN",nameDE="PRIVATGARTEN", typeEN="EXTENSIONS",typeDE="ERWEITERUNGEN",height=0, slots=0, green=true, greenSlots=1, rewardUrban=true, rewardCount=6},
  151. {id=26, column=7, row=2,nameEN="HOUSE-GARDEN",nameDE="PRIVATGARTEN", typeEN="EXTENSIONS",typeDE="ERWEITERUNGEN",height=0, slots=0, green=true, greenSlots=1, rewardUrban=true, rewardCount=6},
  152. {id=27, column=7, row=3,nameEN="HOUSE-GARDEN",nameDE="PRIVATGARTEN", typeEN="EXTENSIONS",typeDE="ERWEITERUNGEN",height=0, slots=0, green=true, greenSlots=1, rewardUrban=true, rewardCount=6},
  153. {id=28, column=7, row=4,nameEN="HOUSE-GARDEN",nameDE="PRIVATGARTEN", typeEN="EXTENSIONS",typeDE="ERWEITERUNGEN",height=0, slots=0, green=true, greenSlots=1, rewardUrban=true, rewardCount=6},
  154. ---green gathering spaces
  155. {id=29, column=8, row=1,nameEN="OPEN-АIR-CINEMA",nameDE="FREILUFTKINO", typeEN="GATHERING SPACES",typeDE="TREFFPUNKTE",height=8, slots=3, green=true, greenSlots=3, rewardUrban=true, rewardCount=9},
  156. {id=30, column=8, row=2,nameEN="OPEN-AIR-SWIMMING-POOL",nameDE="FREIBAD", typeEN="GATHERING SPACES",typeDE="TREFFPUNKTE",height=8, slots=3, green=true, greenSlots=3, rewardUrban=true, rewardCount=9},
  157. {id=31, column=8, row=3,nameEN="GREEN-CAFE",nameDE="GRÜNES CAFÉ", typeEN="GATHERING SPACES",typeDE="TREFFPUNKTE",height=8, slots=3, green=true, greenSlots=3, rewardUrban=true, rewardCount=9},
  158. {id=32, column=8, row=4,nameEN="PALM-TREE-HOUSE",nameDE="PALMENGARTEN", typeEN="GATHERING SPACES",typeDE="TREFFPUNKTE",height=8, slots=3, green=true, greenSlots=3, rewardUrban=true, rewardCount=9},
  159. ----urban gathering spaces
  160. {id=33, column=9, row=1,nameEN="CINEMA",nameDE="KINO", typeEN="GATHERING SPACES",typeDE="TREFFPUNKTE",height=8, slots=3, green=false, greenSlots=0, rewardUrban=false, rewardCount=9},
  161. {id=34, column=9, row=2,nameEN="CONFERENCE-HALL",nameDE="KONFERENZHALLE", typeEN="GATHERING SPACES",typeDE="TREFFPUNKTE",height=8, slots=3, green=false, greenSlots=0, rewardUrban=false, rewardCount=9},
  162. {id=35, column=9, row=3,nameEN="CAFÉ",nameDE="CAFÉ", typeEN="GATHERING SPACES",typeDE="TREFFPUNKTE",height=8, slots=3, green=false, greenSlots=0, rewardUrban=false, rewardCount=9},
  163. {id=36, column=9, row=4,nameEN="ART-GALLERY",nameDE="KUNSTGALERIE", typeEN="GATHERING SPACES",typeDE="TREFFPUNKTE",height=8, slots=3, green=false, greenSlots=0, rewardUrban=false, rewardCount=9},
  164. ---green-roof houses
  165. {id=37, column=10, row=1,nameEN="GREEN-ROOF-HOUSE",nameDE="GRÜNES EINFAMILIENHAUS", typeEN="HOUSES",typeDE="HÄUSER",height=10, slots=2, green=true, greenSlots=2, rewardUrban=true, rewardCount=4},
  166. {id=38, column=10, row=2,nameEN="GREEN-ROOF-HOUSE",nameDE="GRÜNES EINFAMILIENHAUS", typeEN="HOUSES",typeDE="HÄUSER",height=10, slots=2, green=true, greenSlots=2, rewardUrban=true, rewardCount=4},
  167. {id=39, column=10, row=3,nameEN="GREEN-ROOF-HOUSE",nameDE="GRÜNES EINFAMILIENHAUS", typeEN="HOUSES",typeDE="HÄUSER",height=10, slots=2, green=true, greenSlots=2, rewardUrban=true, rewardCount=4},
  168. {id=40, column=10, row=4,nameEN="GREEN-ROOF-HOUSE",nameDE="GRÜNES EINFAMILIENHAUS", typeEN="HOUSES",typeDE="HÄUSER",height=10, slots=2, green=true, greenSlots=2, rewardUrban=true, rewardCount=4},
  169. }
  170.  
  171.  
  172. --PARTICLE FUNCTIONS
  173. function searchParticle(x,y,z)
  174. commands.async.particle("fireworksSpark",x,y,z,0.01,3,0.01,0.01,100)
  175. end
  176.  
  177. function successParticle(x,y,z)
  178. commands.async.particle("happyVillager",x,y,z,2,2,2,1,1000)
  179. commands.async.playsound("random.levelup","@a",x,y,z,1,1.2)
  180. end
  181.  
  182. function failParticle(x,y,z)
  183. commands.async.particle("reddust",x,y,z,0.1,0.1,1.5,1,200)
  184. commands.async.particle("reddust",x,y,z,1.5,0.1,0.1,1,200)
  185. commands.async.playsound("random.bowhit","@a",x,y,z,1,0.8)
  186. end
  187.  
  188. --vocab constructor. Enforces some data structure
  189. function newVocabZone(x,y,z,w,id, reward,nameEN, nameDE, typeEN, typeDE, height, slots,green,greenSlots, rewardUrban, rewardCount)
  190. local nvz = {}
  191. nvz.x ,nvz.y ,nvz.z ,nvz.w = x,y,z,w
  192.  
  193. nvz.cx = nvz.x - nvz.w - 2
  194. nvz.cy = nvz.y
  195. nvz.cz = nvz.z
  196. nvz.nameEN = nameEN
  197. nvz.reward = reward
  198. --- new stuff
  199. nvz.id = id
  200. nvz.nameDE = nameDE
  201. nvz.typeEN = typeEN
  202. nvz.typeDE = typeDE
  203. nvz.height = height
  204. nvz.slots = slots
  205. nvz.green = green
  206. nvz.greenSlots = greenSlots
  207. nvz.rewardUrban = rewardUrban
  208. nvz.rewardCount = rewardCount
  209.  
  210. return nvz
  211.  
  212. end
  213.  
  214. --a multi builder which uses the vocab constructor to create sets of vocab
  215. local function makeVocabZones(quant,w)
  216. local x,y,z = VOCAB_LOCATION.x, VOCAB_LOCATION.y, VOCAB_LOCATION.z
  217. local result = {}
  218. local id = 1
  219. for i=0,quant-1 do
  220. for k=0,3 do
  221. local zpos = i-4
  222. local ypos = k
  223. --print("vocab at X")
  224. --print(x-(2*w)-6)
  225. --print("and Z")
  226. --print(z+((w+1)*zpos))
  227. local nextVocab = newVocabZone(
  228. x-(2*w)-6,y+(ypos*(VOCAB_HEIGHT+3)),
  229. z+((w+1)*zpos),
  230. w,
  231. id,
  232. REWARDS[id] or DEFAULT_REWARD,
  233. VOCABS_DATA[id].nameEN or DEFAULT_NAME,
  234. VOCABS_DATA[id].nameDE or DEFAULT_NAME,
  235. VOCABS_DATA[id].typeEN,
  236. VOCABS_DATA[id].typeDE,
  237. VOCABS_DATA[id].height,
  238. VOCABS_DATA[id].slots,
  239. VOCABS_DATA[id].green,
  240. VOCABS_DATA[id].greenSlots,
  241. VOCABS_DATA[id].rewardUrban,
  242. VOCABS_DATA[id].rewardCount
  243. )
  244. table.insert(result,nextVocab)
  245. id = id +1
  246. end
  247. end
  248. return result
  249. end
  250.  
  251. --constructor for player object so that data structure is consistant
  252. function newPlayerData(name,x,y,z)
  253. local p = {
  254. name = name,
  255. x=x,
  256. y=y,
  257. z=z
  258. }
  259. return p
  260. end
  261.  
  262. local function printall(text,zone)
  263. local text = text..": "
  264. for i,_ in pairs(zone) do
  265. if i == "waitingForCheck" then
  266. text = text..i..", "
  267. end
  268. end
  269. --print(text)
  270. end
  271.  
  272. --return a list of all players in the game world as player objects
  273. local function getNameFromMessage(message)
  274. local names = {}
  275.  
  276. local wordpattern = "[^, ]+"
  277. local numberpattern = "[%-% ]%d+[%.]%d+"
  278. local words,numbers = {},{}
  279.  
  280. for word in string.gmatch(message, wordpattern) do
  281. table.insert(words,word)
  282. end
  283.  
  284. for number in string.gmatch(message, numberpattern) do
  285. table.insert(numbers,number)
  286. end
  287.  
  288. local coords = {
  289. x = math.floor(numbers[1]),
  290. y = math.floor(numbers[2]),
  291. z = math.floor(numbers[3])
  292. }
  293. local name = words[2]
  294. return newPlayerData(name,coords.x,coords.y,coords.z)
  295. end
  296.  
  297.  
  298.  
  299. --constructor for a tutorial zone
  300. function newTutZone(x,y,z,vocabZones)
  301. local ntz = {}
  302. ntz.x ,ntz.y ,ntz.z = x,y,z
  303. ntz.endtime = nil
  304. ntz.waitingForCheck = {}
  305. ntz.player = nil
  306. ntz.clean = false
  307. ntz.vocab = vocabZones
  308.  
  309. printall("New zone",ntz)
  310. sleep(1)
  311.  
  312. return ntz
  313. end
  314.  
  315. local function resetZone(zone)
  316.  
  317. end
  318.  
  319.  
  320.  
  321.  
  322. --reset all tutorials. Teleports current players back to the incoming zone. clears all tutorial zones of blocks and resets them.
  323. local function resetAllTutorials()
  324. end
  325.  
  326.  
  327. --gives the same list of items to a list of players
  328. local function giveItems(playerlist,itemlist)
  329. local given = 0
  330. for i,player in ipairs(playerlist) do
  331. --commands.async.clear(player.name)
  332. for j,item in ipairs(itemlist) do
  333. commands.async.give("@a[name="..player.name.."]",item)
  334. given = given +1
  335. end
  336. --giveHomecomer(player.name)
  337. end
  338. return given
  339. end
  340.  
  341. --check for players and fill if needed
  342. local function checkAndFill(zone)
  343. local iz = INCOMING_ZONE
  344. local result,msg = commands.tp("@p[x="..iz.x..",y="..iz.y..",z="..iz.z..",dx="..iz.w..",dy="..iz.h..",dz="..iz.l.."]",zone.x+START_POINT_OFFSET.x,zone.y+START_POINT_OFFSET.y,zone.z+START_POINT_OFFSET.z,90,0)
  345. if result then
  346. local player = getNameFromMessage(msg[1])
  347. commands.spawnpoint(player.name,TUT_WAIT_AREA.x,TUT_WAIT_AREA.y,TUT_WAIT_AREA.z,TUT_WAIT_AREA.r1,TUT_WAIT_AREA.r2)
  348. local result,msg = commands.scoreboard("players","set",player.name,"tut_state",1)
  349. zone.player = player
  350. commands.clear(player.name)
  351. --giveItems({player},STARTING_ITEMS) --give starting items
  352. zone.endtime = os.clock()+TUT_TIMEOUT_SECONDS
  353. end
  354. end
  355.  
  356. --check for victory and tp players out
  357. local function checkVictoryAndExit(zone)
  358. --commands.tell(zone.player.name,"Doing Victory section")
  359. local victory_length = 2
  360. local endzone_selector = "@p[name="..zone.player.name..",x="..zone.x..",y="..(zone.y+6)..",z="..(zone.z+math.floor(REFRESH_ZONE.w/2))..",dx="..victory_length..",dy="..REFRESH_ZONE.h..",dz="..REFRESH_ZONE.w.."]"
  361. local result,msg = commands.tp(endzone_selector,OUTGOING_POINT.x,OUTGOING_POINT.y,OUTGOING_POINT.z,OUTGOING_POINT.a,OUTGOING_POINT.b)
  362. if result then
  363. zone.clean = false
  364. commands.spawnpoint(zone.player.name,PLAY_AREA.x,PLAY_AREA.y,PLAY_AREA.z,PLAY_AREA.r1,PLAY_AREA.r2)
  365. commands.scoreboard("players","set",zone.player.name,"tut_state",2)
  366. --tell the player they succeeded
  367. --commands.tell(zone.player.name,"You completed the Tutorial")
  368. --announce in English
  369. commands.async.tellraw(zone.player.name,'["",{"text":"Bravo! You completed the building tutorial!","color":"white"}]')
  370. -- announce in German
  371. commands.async.tellraw(zone.player.name,'["",{"text":"Bravo! Du hast das Tutorial abgeschlossen!","color":"gold"}]')
  372. ---
  373. --clear players inventory
  374. commands.clear(zone.player.name)
  375. zone.player = nil
  376. elseif os.clock() > zone.endtime then
  377. zone.clean = false
  378. commands.tell(zone.player.name,"The tutorial timed out")
  379. local zone_select = "@p[name="..zone.player.name..",x="..zone.x..",y="..zone.y..",z="..zone.z..",dx="..REFRESH_ZONE.l..",dy="..REFRESH_ZONE.h..",dz="..REFRESH_ZONE.w.."]"
  380. commands.tp(zone_select,TUT_WAIT_AREA.x,TUT_WAIT_AREA.y,TUT_WAIT_AREA.z,TUT_WAIT_AREA.r1,TUT_WAIT_AREA.r2)
  381. commands.clear(zone.player)
  382. zone.player = nil
  383. end
  384. end
  385.  
  386. -- zone clean up
  387. local function cleanZone(zone)
  388. local rz = REFRESH_ZONE
  389. commands.clone(rz.x,rz.y,rz.z,rz.x+rz.l,rz.y+rz.h,rz.z+rz.w,zone.x,zone.y,zone.z,"replace")
  390. --commands.say("cleaned zone")
  391. zone.clean = true
  392. end
  393.  
  394. --returns a list of player objects containing all players who are standing on the given block, and who also are in the given selection
  395. local function getAllOnBlockType(block,selector)
  396. local result, message = commands.exec("execute @a["..selector.."] ~ ~ ~ detect ~ ~-1 ~ "..block.." -1 tp @p[r=1] ~ ~ ~")
  397. local names = {}
  398. if result == true then
  399. for i,result in ipairs(message) do
  400. local wordpattern = "[^, ]+"
  401. local numberpattern = "[%-% ]%d+[%.]%d+"
  402. local words,numbers = {},{}
  403.  
  404. for word in string.gmatch(result, wordpattern) do table.insert(words,word) end
  405. for number in string.gmatch(result, numberpattern) do table.insert(numbers,number) end
  406.  
  407. if numbers[1] and numbers[2] and numbers[3] then
  408. local coords = {
  409. x = math.floor(numbers[1]),
  410. y = math.floor(numbers[2]),
  411. z = math.floor(numbers[3])
  412. }
  413. local name = words[2]
  414. table.insert(names,newPlayerData(name,coords.x,coords.y,coords.z))
  415. --print("Found a player - getOnBlock")
  416. else
  417. --print("Error: Coordinate Numbers were missing")
  418. end
  419. end
  420. end
  421. return names
  422. end
  423.  
  424. --makes sure that incoming check requests dont exist already
  425. function addToChecklist(player,zone)
  426. for _, detector in ipairs(zone.waitingForCheck) do
  427. if detector.x == player.x and detector.y == player.y and detector.z == player.z then
  428. printall("before return false",zone)
  429. return false
  430. end
  431. end
  432. printall("before table add",zone)
  433. table.insert(zone.waitingForCheck,player)
  434. return true
  435. end
  436.  
  437. --removed all barrier blocks from a buildzone which are used to carve space in vocabs
  438. function cleanBarriers(buildzone)
  439. for h=0,50 do
  440. commands.async.fill(buildzone.x,buildzone.y+h,buildzone.z,buildzone.x+REFRESH_ZONE.w,buildzone.y+h,buildzone.z+REFRESH_ZONE.l,"minecraft:air",0,"replace","minecraft:barrier")
  441. end
  442. end
  443.  
  444. --The main chunk of code which deals with stepping on detector blocks and reading the vocab. Modified for tutorial
  445. function doVocabGameplay(zone)
  446. local selector = "x="..zone.x..",y="..(zone.y-5)..",z="..zone.z..",dx="..REFRESH_ZONE.l..",dy="..REFRESH_ZONE.h..",dz="..REFRESH_ZONE.w
  447.  
  448. local victory = false
  449. --get all players on diamond, add them to the list of things to check
  450. local detectLocations = getAllOnBlockType(BLOCKS.DETECT.block,selector)
  451. for _, player in ipairs(detectLocations) do
  452. addToChecklist(player,zone)
  453. end
  454. --if zone and zone.waitingForCheck then print("found waiting for check") else print("found nothing") end
  455. --DEAL WITH THE DETECTOR AT THE TOP OF THE LIST IF THERE IS ONE
  456. if #zone.waitingForCheck > 0 then
  457. --DO PARTICLE EFFECTS IF A DETECTING BLOCK THAT IS DETECTING
  458. for i,loc in ipairs(zone.waitingForCheck) do
  459. searchParticle(loc.x,loc.y+1,loc.z)
  460. end
  461. local totalResult = false
  462. local checked = table.remove(zone.waitingForCheck,1)
  463. local x,y,z,name = checked.x,checked.y,checked.z,checked.name
  464. for i,vocab in pairs(zone.vocab) do
  465. local vx,vy,vz,vx1,vy1,vz1 = vocab.x, vocab.y, vocab.z, vocab.x+vocab.w, vocab.y+VOCAB_HEIGHT, vocab.z+vocab.w
  466. local dx,dy,dz = x-math.floor(vocab.w/2),y-1,z-math.floor(vocab.w/2)
  467. --print("Comparing "..vx..","..vy..","..vz.." with "..dx..","..dy..","..dz)
  468. local result,message = commands.testforblocks(vx,vy,vz,vx1,vy1,vz1,dx,dy,dz,"masked")
  469. --print(message[1])
  470. if result then
  471. --clone in the correct vocab
  472. 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")
  473. if DEBUG_MODE then
  474. print(clonemes[1])
  475. end
  476. commands.async.clear(name)
  477. commands.async.give(name,pickaxe)
  478. commands.async.give(name,vocab.reward)
  479. -- announce vocab success in English
  480. local rewardType = 'nature'
  481. local rewardTypeDE = 'grüne'
  482. if vocab.rewardUrban then
  483. rewardType = 'urban'
  484. rewardTypeDE = 'urbane'
  485. end
  486. commands.async.tellraw(name,'["",{"text":"You built a '..vocab.nameEN.. ' ('..vocab.typeEN..'), which is '..vocab.height..'m tall and gives '..vocab.slots..' density pts, '..vocab.greenSlots..' green pts and '..vocab.rewardCount..'x '..rewardType..' resource!","color":"white"}]')
  487. -- announce vocab success in German
  488. commands.async.tellraw(name,'["",{"text":"Du hast ein '..vocab.typeDE..' | '..vocab.nameDE.. ' gebaut, das '..vocab.height..' Meter hoch ist und dir '..vocab.slots..' Punkte für die Dichte einbringt, jedoch '..vocab.greenSlots..' Punkte für Grünflächen und '..vocab.rewardCount..' '..rewardTypeDE..' Ressourcen!","color":"gold"}]')
  489. --clear out barrier blocks
  490. cleanBarriers(zone)
  491.  
  492. totalResult = true
  493. break
  494.  
  495. end
  496. end
  497. if totalResult then
  498. --yey win, do a happy time
  499. successParticle(x,y,z)
  500. else
  501. --no vocab found so do a fail particle
  502. --announce in English
  503. commands.async.tellraw(name,'["",{"text":"The shape you have built does not match any shape in the catalogue, try a different one.","color":"red"}]')
  504. -- announce in German
  505. commands.async.tellraw(name,'["",{"text":"Die Kombination, die du gebaut hast passt leider zu keinem Gebäude, versuche es mit einer anderen Form.","color":"gold"}]')
  506. failParticle(x,y-1,z)
  507. end
  508. end
  509. return victory
  510. end
  511.  
  512. --do all logic for tutzones
  513. local function updateTutZones(tuts)
  514. --all empty zones check for players and get if available
  515. for index,zone in ipairs(tuts.zones) do
  516. if zone.player == nil then
  517. printall("fill zone "..index,zone)
  518. checkAndFill(zone)
  519. end
  520. end
  521.  
  522.  
  523. --all zones with player, check vocab update
  524. for index,zone in ipairs(tuts.zones) do
  525. if zone.player then
  526. printall("gameplay "..index,zone)
  527. doVocabGameplay(zone)
  528. end
  529. end
  530.  
  531.  
  532.  
  533. --all zones with players check for victory and tp players out
  534. for index,zone in ipairs(tuts.zones) do
  535. if zone.player then
  536. printall("exit "..index,zone)
  537. checkVictoryAndExit(zone)
  538. end
  539. end
  540.  
  541.  
  542. --all empty zones which need cleaning are cleaned up
  543. for index,zone in ipairs(tuts.zones) do
  544. if zone.clean == false then
  545. printall("clean "..index,zone)
  546. cleanZone(zone)
  547. end
  548. end
  549.  
  550.  
  551. end
  552.  
  553. --setup a new tuts object
  554. local function setup()
  555. local tuts = {}
  556. tuts.zones = {}
  557.  
  558. --generate vocab rewards
  559. for i=1,#VOCABS_DATA do
  560. if VOCABS_DATA[i].rewardUrban then
  561. REWARDS[i] = houseBlock(VOCABS_DATA[i].rewardCount)
  562. else
  563. REWARDS[i] = gardenBlock(VOCABS_DATA[i].rewardCount)
  564. end
  565. end
  566.  
  567. tuts.vocabs = makeVocabZones(NUMBER_OF_VOCAB,VOCAB_WIDTH)
  568. --print(type(tuts.vocabs),#tuts.vocabs)
  569. local rz = REFRESH_ZONE
  570. --local vocab_subset = {}
  571. --for i=1, 40 in ipairs(TUTORIAL_VOCABS) do
  572. -- table.insert(vocab_subset,tuts.vocabs[value])
  573. --end
  574.  
  575. for index = 1, NUMBER_OF_TUT_ZONES do
  576. local newZone = newTutZone(rz.x,rz.y,rz.z+(index*(rz.w+1+WALL_THICKNESS)),tuts.vocabs)
  577. table.insert(tuts.zones,newZone)
  578. end
  579.  
  580. --check for vocab zone at vocab location
  581. --build all vocab locations
  582.  
  583. --store vocab in tuts object
  584.  
  585. return tuts
  586. end
  587.  
  588.  
  589.  
  590. local symbols = {
  591. "(X) ",
  592. "(-) "
  593. }
  594. local spin = 1
  595.  
  596. --BEGIN RUNTIME CODE
  597. local blink = true
  598. local tuts = setup()
  599. while true do
  600. if not DEBUG_MODE then
  601. term.clear()
  602. print("Controlling Tutorial "..symbols[spin])
  603. spin = spin +1
  604. if spin > #symbols then spin = 1 end
  605. end
  606. updateTutZones(tuts)
  607. commands.async.weather("clear",10000)
  608.  
  609. local resetbutton = redstone.getInput("left")
  610. if resetbutton then
  611. print("reset!")
  612. resetAllTutorials()
  613. end
  614. sleep(0.5)
  615. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement