Pastebin
API
tools
faq
paste
Login
Sign up
Please fix the following errors:
New Paste
Syntax Highlighting
local VERSION = '0.8.6 - updated rewards and goals' os.loadAPI('tracker') os.loadAPI('json') print("Starting 20.000 Blocks") DEBUG_MODE = false local monitor = peripheral.wrap("right") local ox,oy,oz = commands.getBlockPosition() CITY_VERSION = 1 -- this denotes which iteration of the map is current. When the map is full, i.e. all buildzones have been played we replace it with an empty one and increase the city vesrion with 1 SPAWN_VILLAGER = false DO_GRID = true GRID_HOLE_CHANCE = 0 NUMBER_OF_BUILDZONES = 6 NUMBER_OF_VOCAB = 10 GAME_LENGTH = 600 VOCAB_WIDTH = 27 VOCAB_HEIGHT = 19 BUILDZONE_WIDTH = 62 -- the actual zone width is 63 blocks, but for some reason due to how minecraft handles relative coordinates this has to be 62 BUILDZONE_FLOOR_HEIGHT = -1 HOMECOMER_TYPE = "Pig" HOMECOMER_VALUE = 90 --90 is for pig SPAWN = { x=12110, y=57, z=-1777, a1=90, a2=0 } FIRSTZONE= { x=11685, y=57, z=-1869 } WAITZONE = { x=12093, y=56, z=-1779, w=5, l=5 } --this is the block at ~-4 ~ ~-4 from the corner of the shape zone --i.e., (the one with the grammar shape in it) of the vocab that is closest to zero FIRSTVOCAB= { x=-60, y=57, z=-107 } VICTORY_HEIGHT = 30 VICTORY_TOTAL = 50 VICTORY_SPECIFIC = {name='garden',count=101} WOOL_PER_EMERALD = 64 PICKAXE_USES = 40 BLOCKS = { CAMP_FLOOR = {block='minecraft:sandstone',data=0}, CONSTRUCTION = {block='minecraft:diamond_ore',data=0}, RING = {block='minecraft:diamond_ore',data=0}, DETECT = {block='minecraft:red_sandstone',data=0}, DETECT_DEAD = {block='minecraft:obsidian',data=0}, VOCAB_DETECT = {block="minecraft:quartz_block",data=0}, VOCAB_REPLACE = {block="minecraft:coal_block",data=0}, VICTORY_MARKER = {block="minecraft:emerald_block",data=0}, PLUG = {block="minecraft:lapis_ore",data=0}, PHVFLOOR = {block="minecraft:stone_slab",data=3}, BUILDING_HOUSE = {block="minecraft:wool",data=0}, BUILDING_GARDEN = {block="minecraft:wool",data=13}, BUILDING_WATER = {block="minecraft:wool",data=1}, _matWhiteSmooth ={block="mincreaft:stained_hardened_clay",data=0}, _matWhiteSmooth2 = {block="minecraft:brick_block",data=0}, _matYellowSmooth = {block="minecraft:stained_hardened_clay",data=4}, _matPinkSmooth = {block="minecraft:stained_hardened_clay",data=6}, _matBlueSmooth = {block="minecraft:stained_hardened_clay",data=9}, _matPurpleSmooth = {block="minecraft:stained_hardened_clay",data=10}, _matWhiteTextured = {block="minecraft:planks",data=4}, _matYellowTextured = {block="minecraft:planks",data=1}, _matPinkTextured = {block="minecraft:planks",data=0}, _matBlueTextured = {block="minecraft:planks",data=2}, _matPurpleTextured = {block="minecraft:planks",data=5}, } --contains a list of all posible Buildzones (build a bit later) LOCS = {} if DEBUG_MODE then GAME_LENGTH = 12000 NUMBER_OF_BUILDZONES = 1 end --creates a grid of absolute references (0,0) (1,0) function buildGrid(w,h) local grid = {} for x=0,w-1 do for z=0,h-1 do table.insert(grid,{x=x,z=z}) end end return grid end --sets where and how big the PHV area is --second number is along the long edge of PHV starting at the spawn side --first number is along the short edge of PHV starting from the park side if DEBUG_MODE then FIRSTZONE= { x=5, y=57, z=-7 } LOCS = buildGrid(1,3) else LOCS = buildGrid(11,27) end --call these to return a proper minecraft item string including adventure mode properties function houseBlock(quant) text = BLOCKS.BUILDING_HOUSE.block..' '..quant..' '..BLOCKS.BUILDING_HOUSE.data..' {display:{Name:"Urban Resource",Lore:[Place this against a Detector to build denser, more urban buildings]},CanPlaceOn:["'..BLOCKS.BUILDING_HOUSE.block..'","'..BLOCKS.PLUG.block..'","'..BLOCKS.DETECT.block..'"]}' return text end function gardenBlock(quant) text = BLOCKS.BUILDING_GARDEN.block..' '..quant..' '..BLOCKS.BUILDING_GARDEN.data..' {display:{Name:"Nature Resource",Lore:[Place this against a Detector to build greener, more open buildings]},CanPlaceOn:["'..BLOCKS.BUILDING_HOUSE.block..'","'..BLOCKS.PLUG.block..'","'..BLOCKS.DETECT.block..'"]}' return text end STARTING_ITEMS = { houseBlock(30), gardenBlock(30), 'stone_pickaxe 1 '..131-PICKAXE_USES..' {CanDestroy:["'..BLOCKS.BUILDING_HOUSE.block..'"],display:{Name:"Pickaxe",Lore:[Use this to remove up to '..PICKAXE_USES..' pieces of construction material]}}' } DEFAULT_NAME = 'BUILDING' --[[ VOCAB_NAMES = { 'freestand-house', 'freestand-house', 'freestand-house', 'freestand-house', 'dbl-ext-house', 'dbl-ext-house', 'dbl-ext-house', 'dbl-ext-house', 'bridge-house', 'bridge-house', 'bridge-garden', 'bridge-garden', 'ext-house', 'ext-house', 'ext-house', 'ext-house', 'riser-1', 'riser-2', 'city-garden', 'city-plaza', 'dbl-ext-garden', 'dbl-ext-garden', 'dbl-ext-garden', 'dbl-ext-garden', 'ext-garden', 'ext-garden', 'ext-garden', 'ext-garden', 'corner-garden', 'corner-garden', 'corner-garden', 'corner-garden', 'corner-house', 'corner-house', 'corner-house', 'corner-house', 'freestand-garden', 'freestand-garden', 'freestand-garden', 'freestand-garden' } --]] ---------------------------------------------------------------------------------------------------------------- -- the data structure below represents the catalogue of vocabularies as built in minecraft -- id - is unique for each vocab, starting from 1 going to 40 currently -- column and row - represent the "physical" location of the vocab model in the catalogue in the minecraft world -- nameEN and name DE - are names for english and german. for now english names must not have spaces, use dashes (-) instead -- typeEN and typeDE - are the type names, also in english and german such as tech&science spaces -- height - is how many blocks is this structure tall -- slots - is how many potential detector stones is this structure occupying as a building, ex. 2 for houses, 3 for corner extenstions, 0 for plazas -- green - is true or false and is used for easier calculation of the GREENEST GOAL - we dont use this field now and can be removed -- greenSlots - is how many slots are green and is used for easier calculation of the GREENEST GOAL VOCABS_DATA = { -- urban houses {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}, {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}, {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}, {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}, -- urban businesses {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}, {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}, {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}, {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}, -- urban tech&science spaces {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}, {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}, -- green tech&science spaces {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}, {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}, -- urban house extensions {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}, {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}, {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}, {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}, --risers {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}, {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}, --plazas {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}, {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}, --green businesses {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}, {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}, {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}, {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}, ---green private garden extensions {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}, {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}, {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}, {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}, ---green gathering spaces {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}, {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}, {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}, {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}, ----urban gathering spaces {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}, {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}, {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}, {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}, ---green-roof houses {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}, {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}, {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}, {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}, } DEFAULT_REWARD = houseBlock(4) REWARDS = {} --[[ --Urban singlehouse rewards (costs 4 house, -2+2 activators) REWARDS[1] = gardenBlock(4) REWARDS[2] = gardenBlock(4) REWARDS[3] = gardenBlock(4) REWARDS[4] = gardenBlock(4) --Urban businesses rewards (costs 6 house, -2+1 activators) REWARDS[5] = gardenBlock(8) REWARDS[6] = gardenBlock(8) REWARDS[7] = gardenBlock(8) REWARDS[8] = gardenBlock(8) --Urban Tech&Science Spaces bridge rewards (costs 6 house, -3+2 activators) REWARDS[9] = gardenBlock(10) REWARDS[10] = gardenBlock(10) --Green Tech&Science Spaces garden bridge (costs 6 garden, -3+2 activators) REWARDS[11] = houseBlock(10) REWARDS[12] = houseBlock(10) --House extension rewards (costs 4 house, 1 activators) REWARDS[13] = gardenBlock(6) REWARDS[14] = gardenBlock(6) REWARDS[15] = gardenBlock(6) REWARDS[16] = gardenBlock(6) --riser 2 (costs 12 house) REWARDS[17] = houseBlock(6) --riser 1 (costs 8 house) REWARDS[18] = houseBlock(4) --plaza city (costs 4 house, -1 activator) REWARDS[19] = gardenBlock(2) --plaza park (costs 4 garden, -1 activator) REWARDS[20] = houseBlock(2) --green businesses (costs 6 garden, -2+1 activators) REWARDS[21] = houseBlock(8) REWARDS[22] = houseBlock(8) REWARDS[23] = houseBlock(8) REWARDS[24] = houseBlock(8) --extension-private garden rewards (costs 3 garden, -1 activators) REWARDS[25] = houseBlock(6) REWARDS[26] = houseBlock(6) REWARDS[27] = houseBlock(6) REWARDS[28] = houseBlock(6) --L-shaped green gathering places (costs 6 garden, -3+3 activators) REWARDS[29] = houseBlock(9) REWARDS[30] = houseBlock(9) REWARDS[31] = houseBlock(9) REWARDS[32] = houseBlock(9) --L-shaped urban gathering places (costs 6 house, -3+3 activators) REWARDS[33] = gardenBlock(9) REWARDS[34] = gardenBlock(9) REWARDS[35] = gardenBlock(9) REWARDS[36] = gardenBlock(9) --green-roof houses (costs 4 garden, -2+2 activators) REWARDS[37] = houseBlock(4) REWARDS[38] = houseBlock(4) REWARDS[39] = houseBlock(4) REWARDS[40] = houseBlock(4) --]] --constructor for player object so that data structure is consistant function newPlayerData(name,x,y,z) local p = { name = name, x=x, y=y, z=z } return p end --return a list of all players in the game world as player objects local function getAllPos(selector) local result, message = commands.tp("@a["..selector.."]","~ ~ ~") local names = {} if result == true then for i,result in ipairs(message) do local wordpattern = "[^, ]+" local numberpattern = "[%-% ]%d+[%.]%d+" local words,numbers = {},{} for word in string.gmatch(result, wordpattern) do table.insert(words,word) end for number in string.gmatch(result, numberpattern) do table.insert(numbers,number) end local coords = { x = math.floor(numbers[1]), y = math.floor(numbers[2]), z = math.floor(numbers[3]) } local name = words[2] table.insert(names,newPlayerData(name,coords.x,coords.y,coords.z)) --print("Player Found - getAllPos") end end return names end --sort table by random local function shuffleTable( t ) local rand = math.random assert( t, "shuffleTable() expected a table, got nil" ) local iterations = #t local j for i = iterations, 2, -1 do j = rand(i) t[i], t[j] = t[j], t[i] end end --returns a list of player objects containing all players who are standing on the given block, and who also are in the given selection local function getAllOnBlockType(block,selector) local result, message = commands.exec("execute @a["..selector.."] ~ ~ ~ detect ~ ~-1 ~ "..block.." -1 tp @p[r=1] ~ ~ ~") local names = {} if result == true then for i,result in ipairs(message) do local wordpattern = "[^, ]+" local numberpattern = "[%-% ]%d+[%.]%d+" local words,numbers = {},{} for word in string.gmatch(result, wordpattern) do table.insert(words,word) end for number in string.gmatch(result, numberpattern) do table.insert(numbers,number) end if numbers[1] and numbers[2] and numbers[3] then local coords = { x = math.floor(numbers[1]), y = math.floor(numbers[2]), z = math.floor(numbers[3]) } local name = words[2] table.insert(names,newPlayerData(name,coords.x,coords.y,coords.z)) print("Found a player - getOnBlock") else print("Error: Coordinate Numbers were missing") end end end return names end --gives a player a HOMECOMER egg with their name on it. Removes all spawn eggs first local function giveHomecomer(name) commands.clear(name,'spawn_egg') commands.give(name,'spawn_egg 1 '..HOMECOMER_VALUE..' {CanPlaceOn:["'..BLOCKS.PHVFLOOR.block..'","'..BLOCKS.CAMP_FLOOR.block..'","'..BLOCKS._matWhiteSmooth..'","'..BLOCKS._matWhiteSmooth2..'","'..BLOCKS._matYellowSmooth..'","'..BLOCKS._matPinkSmooth..'","'..BLOCKS._matBlueSmooth..'","'..BLOCKS._matPurpleSmooth..'","'..BLOCKS._matWhiteTextured..'","'..BLOCKS._matYellowTextured..'","'..BLOCKS._matPinkTextured..'","'..BLOCKS._matBlueTextured..'","'..BLOCKS._matPurpleTextured..'"],display:{Name:"HOMECOMER - '..name..'",Lore:[Use this on the floor to return to spawn]}}') end --returns a list of HOMECOMER entities and their names local function getHomecomers() local result, message = commands.exec("execute @e[type="..HOMECOMER_TYPE.."] ~ ~ ~ tp @e[r=1] ~ ~ ~") local names = {} if result == true then for i,result in ipairs(message) do local wordpattern = "[^, ]+" local numberpattern = "[%-% ]%d+[%.]%d+" local words,numbers = {},{} for word in string.gmatch(result, wordpattern) do table.insert(words,word) print(word) end for number in string.gmatch(result, numberpattern) do table.insert(numbers,number) end if numbers[1] and numbers[2] and numbers[3] then local coords = { x = math.floor(numbers[1]), y = math.floor(numbers[2]), z = math.floor(numbers[3]) } local name = words[4] table.insert(names,newPlayerData(name,coords.x,coords.y,coords.z)) print("Found a player - getOnBlock "..name) else print("Error: Coordinate Numbers were missing") end end end return names end local function removePlayerFromKew(game,playername) for _,kew in pairs(game.queues) do for index, player in ipairs(kew.playerlist) do if player.name == playername then table.remove(kew.playerlist,index) end end if #kew.playerlist == 0 and kew.phase == 2 then --game can be ended as no players are left kew.timer = 0 end end end local function movePlayerToSpawn(playername) respawnPlayer(playername) commands.async.tp(playername,SPAWN.x,SPAWN.y,SPAWN.z,SPAWN.a1,SPAWN.a2) commands.async.tellraw(playername,'["",{"text":"You used your HOMECOMER and TELEPORTED BACK TO SPAWN","color":"white"}]') commands.async.tellraw(playername,'["",{"text":"DE: TELEPORTED: You used your Heimkehrer","color":"gold"}]') end --takes a list of homecomers and deals with all those players, moving them back to spawn and removing them from game --also gives them a new homecomer local function dealWithHomecomers(game, homecomers) for _,homecomer in pairs(homecomers) do --remove player from current game if in game removePlayerFromKew(game,homecomer.name) --teleport them back to spawn movePlayerToSpawn(homecomer.name) --give a new homecomer giveHomecomer(homecomer.name) --particle effects --teleport message end --kill all homecomers if #homecomers>0 then commands.tp("@e[type="..HOMECOMER_TYPE.."]",100000,200,100000) commands.kill("@e[type="..HOMECOMER_TYPE.."]") os.sleep(#homecomers*0.2) end end --creates a villager with special items local function spawnVillager(x,y,z) 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"]}}} ]}}') end --displays a time as experience points to a selection of players local function displayTime(selector,minutes,seconds) --commands.title("@a["..selector.."]","subtitle",'{text:"Time left: '..minutes..":"..seconds..'",color:red,bold:false,underlined:false,italic:false,strikethrough:false,obfuscated:false}') commands.async.xp("-1000000L","@a["..selector.."]") local secondstot = (minutes * 60) + seconds commands.async.xp(tostring(secondstot).."L","@a["..selector.."]") end --displays a title to a selection of players local function displayTitle(selector,text) commands.async.title("@a["..selector.."]","title",'{text:"'..text..'"}') end --simply runs displayTitle on a list of players local function displayTitleToGroup(playerlist,text) for i,player in ipairs(playerlist) do displayTitle("name="..player.name,text) end end --simply runs displayTime on a list of players local function displayTimeToGroup(playerlist,minutes,seconds) for i,player in ipairs(playerlist) do displayTime("name="..player.name,minutes,seconds) end end --teleports a list of players to an exact place and sends them a message about it local function teleportToPoint(x,y,z,playerlist,clear,textEN, textDE) for i,player in ipairs(playerlist) do player.x = x player.y = y player.z = z commands.async.gamemode(2,player.name) if clear then commands.async.clear(player.name,"wool") commands.async.clear(player.name,"stone_pickaxe") end commands.tp("@a[name="..player.name.."]",x,y,z) commands.async.tellraw(player.name,'["",{"text":"'..textEN..'","color":"white"}]') commands.async.tellraw(player.name,'["",{"text":"'..textDE..'","color":"gold"}]') end end --teleports a list of players to a given buildzone local function teleportToZone(buildzone,playerlist,textEN, textDE) teleportToPoint(buildzone.x+2+(buildzone.w/2),buildzone.y+5,buildzone.z+2+(buildzone.w/2),playerlist,true,textEN, textDE) end --gives the same list of items to a list of players local function giveItems(playerlist,itemlist) local given = 0 for i,player in ipairs(playerlist) do --commands.async.clear(player.name) for j,item in ipairs(itemlist) do commands.async.give("@a[name="..player.name.."]",item) given = given +1 end giveHomecomer(player.name) end return given end --a multi builder which uses the vocab constructor to create sets of vocab local function makeVocabZones(quant,w) local x,y,z = FIRSTVOCAB.x, FIRSTVOCAB.y, FIRSTVOCAB.z local result = {} local id = 1 for i=0,quant-1 do for k=0,3 do local zpos = i-4 local ypos = k --print("vocab at X") --print(x-(2*w)-6) --print("and Z") --print(z+((w+1)*zpos)) local nextVocab = newVocabZone( x-(2*w)-6,y+(ypos*(VOCAB_HEIGHT+3)), z+((w+1)*zpos), w, id, REWARDS[id] or DEFAULT_REWARD, VOCABS_DATA[id].nameEN or DEFAULT_NAME, VOCABS_DATA[id].nameDE or DEFAULT_NAME, VOCABS_DATA[id].typeEN, VOCABS_DATA[id].typeDE, VOCABS_DATA[id].height, VOCABS_DATA[id].slots, VOCABS_DATA[id].green, VOCABS_DATA[id].greenSlots, VOCABS_DATA[id].rewardUrban, VOCABS_DATA[id].rewardCount ) table.insert(result,nextVocab) id = id +1 end end return result end --finds the next free location(or buildzone) for a new game in a given area. --giving force as True will mean it overrides the first location no matter what local function findNextLoc(width,zones,force) local x,y,z = 0,0,0 for i,loc in ipairs(LOCS) do x,y,z = FIRSTZONE.x+(loc.x*(width+1)),FIRSTZONE.y,FIRSTZONE.z+(-loc.z*(width+1)) --print("testing for available zone at: "..x..", "..y..", "..z) local result,message = commands.testforblock(x,y+BUILDZONE_FLOOR_HEIGHT,z,"minecraft:air") --print("testing done") if force then result = true end local zonefree = true for i,zone in ipairs(zones) do if zone.x == x and zone.z == z then zonefree = false end end --print("next position free is ",loc.x*width,oy,loc.z*width) --if result then print("true") else print("false") end if result and zonefree then --print("using loc: ",loc.x,loc.z) return x,y,z end end return nil,nil,nil end --relocates a buildzone to a new coordinate safely --avoids overlapping with other buildzones function moveBuildzone(buildzone,zones) local x,y,z = findNextLoc(buildzone.w,zones) if x and y and z then print("moved buildzone from "..buildzone.x..","..buildzone.z.." to "..x..","..y) local w = buildzone.w buildzone.x,buildzone.y,buildzone.z = x,y+BUILDZONE_FLOOR_HEIGHT,z buildzone.selector = "x="..x..",y="..tostring(y-1)..",z="..z..",dx="..w..",dy=256,dz="..w buildzone.structures = {} --a list of all vocabularies which have been contructed else print("buildzone at "..buildzone.x..","..buildzone.z.." stayed where it is") end end --multi builder to create sets of buildzones using the buildzone constructor local function makeBuildzones(quant,vocab,width,height) local result = {} for i=1,quant do --print("locating available slot") local x,y,z = findNextLoc(width,result) if x and y and z then --print("made new buildzone at",x,y,z) table.insert(result,newBuildZone(x,y+height,z,width,vocab)) else --print("failed to make new buildzone") end end local remaining = NUMBER_OF_BUILDZONES - #result --print("doing this remaining thing") for i=1, remaining do local x,y,z = findNextLoc(width,result,true) if x and y and z then --print("forced new buildzone at",x,y,z) table.insert(result,newBuildZone(x,y+height,z,width,vocab)) else print("failed to force new buildzone") end end return result end --vocab constructor. Enforces some data structure function newVocabZone(x,y,z,w,id, reward,nameEN, nameDE, typeEN, typeDE, height, slots,green,greenSlots, rewardUrban, rewardCount) local nvz = {} nvz.x ,nvz.y ,nvz.z ,nvz.w = x,y,z,w nvz.cx = nvz.x - nvz.w - 2 nvz.cy = nvz.y nvz.cz = nvz.z nvz.nameEN = nameEN nvz.reward = reward --- new stuff nvz.id = id nvz.nameDE = nameDE nvz.typeEN = typeEN nvz.typeDE = typeDE nvz.height = height nvz.slots = slots nvz.green = green nvz.greenSlots = greenSlots nvz.rewardUrban = rewardUrban nvz.rewardCount = rewardCount return nvz end --buildzone constructor. Enforces some data structure function newBuildZone(x,y,z,w,vocabZones) local nbz = {} nbz.x ,nbz.y ,nbz.z ,nbz.w = x,y,z,w nbz.selector = "x="..x..",y="..(y-5)..",z="..z..",dx="..w..",dy=256,dz="..w nbz.structures = {} --a list of all vocabularies names which have been contructed nbz.buildings = {} --a list of all vocabularies with full data (x,y,z,id,name) which have been contructed nbz.filledSlots = 0 --to count how many slots have been filled with buildings. the matrix is 7x7x20 slots. one slot is 9x9x9 blocks big nbz.greenSlots = 0 --to count how many of the slots are green. the matrix is 7x7x20 slots. one slot is 9x9x9 blocks big nbz.variety = {} -- this stores how many buildings of each type are there. it is indexed on vocab.id and the value is the number of buildings from type vocab.id nbz.waitingForCheck = {} nbz.highest = 0 nbz.vocab = vocabZones return nbz end --kew constructor. Enforces some data structure function newQueue(buildzone,maxplayers) local q = {} q.timer = 1 q.phase = 1 q.victory = false q.phases = { { name = "Selecting Players", length = 25, displaylength = 15 }, { name = "Game In Progress", length = GAME_LENGTH, displaylength = 70 }, { name = "Round Complete", length = 35, displaylength = 5 } } q.playerlist = {} q.maxplayers = maxplayers q.buildzone = buildzone return q end --creates a ring of blocks using coordinates function fillRing(x,y,z,w,block) commands.fill(x,y,z,x+w,y,z,block) commands.fill(x+w,y,z,x+w,y,z+w,block) commands.fill(x,y,z+w,x+w,y,z+w,block) commands.fill(x,y,z+w,x,y,z,block) end function setup() print("debug: starting setup function.") local game = {} game.vocab = {} game.builds = {} game.queues = {} game.waitlist = {} game.spawn = SPAWN game.lastClock = os.clock() game.nowTime = os.clock() --generate vocab rewards for i=1,#VOCABS_DATA do if VOCABS_DATA[i].rewardUrban then REWARDS[i] = houseBlock(VOCABS_DATA[i].rewardCount) else REWARDS[i] = gardenBlock(VOCABS_DATA[i].rewardCount) end end --kill all villagers commands.exec("kill @e[type=Villager]") --buildzone and vocabzone creation print("debug-setup: making vocab zones.") game.vocab = makeVocabZones(NUMBER_OF_VOCAB,VOCAB_WIDTH) print("debug-setup: making building zones.") game.builds = makeBuildzones(NUMBER_OF_BUILDZONES,game.vocab,BUILDZONE_WIDTH,BUILDZONE_FLOOR_HEIGHT) for i,build in ipairs(game.builds) do table.insert(game.queues,newQueue(build,4)) end print("debug-setup: testing for properly setup vocabs.") for i,vz in ipairs(game.vocab) do local x,y,z,w = vz.x,vz.y,vz.z,vz.w local cx,cy,cz = vz.cx,vz.cy,vz.cz local detector, message1 = commands.testforblock(x+(math.floor(w/2)),y,z+(math.floor(w/2)),BLOCKS.DETECT.block) local blocker, message2 = commands.testforblock(x+(math.floor(w/2)),y,z+(math.floor(w/2)),BLOCKS.DETECT_DEAD.block) if not (detector or blocker) then for nx=0,2 do for nz=0,2 do commands.setblock(x+(nx*9)+4,y-1,z+(nz*9)+4,BLOCKS.VOCAB_REPLACE.block) commands.setblock(cx+(nx*9)+4,cy-1,cz+(nz*9)+4,BLOCKS.VOCAB_DETECT.block) end end commands.setblock(x+(math.floor(w/2)),y,z+(math.floor(w/2)),BLOCKS.DETECT_DEAD.block) end end print("debug-setup: adding scoreboards.") --[[ for i, name in ipairs(VOCAB_NAMES) do commands.scoreboard("objectives","add",name,"dummy") end --]] print(#VOCABS_DATA) for i=1,#VOCABS_DATA do commands.scoreboard("objectives","add","building_"..i,"dummy") end commands.gamerule("doDaylightCycle",false) commands.gamerule("keepInventory",true) commands.gamerule("doTileDrops",false) commands.gamerule("logAdminCommands",false) commands.gamerule("commandBlockOutput",false) commands.time("set",6000) commands.scoreboard("objectives","add","highscores","dummy","Best Neighbourhoods") commands.scoreboard("objectives","add","VillagerLife","dummy") commands.scoreboard("objectives","add","built","dummy", "Structures Built") commands.scoreboard("objectives","add","highest","dummy", "Personal Highest") commands.scoreboard("objectives","add","played","dummy","Games Played") commands.title("@a","times",0,30,30) -- what does this do? math.randomseed( os.time() ) commands.scoreboard("objectives","setdisplay","sidebar","highscores") commands.scoreboard("objectives","setdisplay","list","played") print("time is: "..os.time()) print( "time is: "..textutils.formatTime( os.time(), false ) ) print("day is: "..os.day()) print("computer clock is: "..os.clock()) if DEBUG_MODE then for i,build in ipairs(game.builds) do build.phase = 2 build.timer = 500 end end print("Computer Co-ordinates ",ox,oy,oz) print("20.000 Blocks Active!") return game end function checkForHomecomers(game) --execute on all homecomers local homecomers = getHomecomers() dealWithHomecomers(game,homecomers) end --main game loop --runs the game object through each of these update steps in order function update(game) local elapsed = updateClock(game) --update players checkPlayers(game) doTimerUpdates(game,elapsed) doPhaseUpdates(game) doPhaseEnds(game) checkBoundaries(game) checkForHomecomers(game) if #game.waitlist > 0 then allocateWaiters(game) end end --calculates elapsed time during a game tick function updateClock(game) game.nowTime = os.clock() local elapsed = game.nowTime - game.lastClock game.lastClock = game.nowTime return elapsed end --updates all kews in the game object based on elapsed time function doTimerUpdates(game,elapsed) for i,kew in ipairs(game.queues) do kew.timer = kew.timer - elapsed end end --check players are inside their buildzone and move them back if not function checkBoundaries(game) for i,kew in ipairs(game.queues) do if kew.phase ==2 then --boundaries local x_min = kew.buildzone.x local x_max = kew.buildzone.x+kew.buildzone.w local z_min = kew.buildzone.z local z_max = kew.buildzone.z+kew.buildzone.w local toBeCorrected = {} for j,player in ipairs(kew.playerlist) do local listOfOne = getAllPos('m=2,name='..player.name) if listOfOne and listOfOne[1] then player.x = listOfOne[1].x player.y = listOfOne[1].y player.z = listOfOne[1].z local changed = false if player.x > x_max then changed = true player.x = x_max-2 end if player.x < x_min then changed = true player.x = x_min+2 end if player.z > z_max then changed = true player.z = z_max-2 end if player.z < z_min then changed = true player.z = z_min+2 end if changed then teleportToPoint(player.x,kew.buildzone.y,player.z,{player},false,"TELEPORTED BACK TO GAME: Please stay inside the building zone or use HOMECOMER to leave the game!", "DE: TELEPORTED: Please stay inside the building zone until your game has ended") end end end end end end --here you can set the logic which determines if a buildzone was valuable. --Return true if it is crap and should be replaced function checkIfBuildzoneIsCrap(buildzone) if #buildzone.structures < 5 then print("Buildzone was crap") return true end print("Buildzone was ok") return false end --Everything that happens after a buildzone was completed --due to time limit. function cleanAfterVictory(buildzone) commands.async.setblock(buildzone.x,buildzone.y,buildzone.z,BLOCKS.VICTORY_MARKER.block) fillRing(buildzone.x,buildzone.y,buildzone.z,buildzone.w,"minecraft:air",0,"replace",BLOCKS.CONSTRUCTION.block,BLOCKS.CONSTRUCTION.data) for h=0,256-buildzone.y do 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) 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) 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) 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) end 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) 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") local wasCrap = checkIfBuildzoneIsCrap(buildzone) if wasCrap then --mark this buildzone for replacement commands.async.setblock(buildzone.x,buildzone.y,buildzone.z,"minecraft:air") end end --these happen every tick and require the game object --updates are performed on each Queue (kew) and within each --of those on each buildzone. function doPhaseUpdates(game) for i,kew in ipairs(game.queues) do local minutes = string.format("%02d",math.floor(kew.timer/60)) local seconds = string.format("%02d",math.floor(kew.timer - (minutes*60))) if kew.timer <= 0 then minutes = "00" seconds = "00" end if kew.phase == 1 then --waiting phase if #kew.playerlist == kew.maxplayers and kew.timer > 5 then kew.timer = 5 end if not DEBUG_MODE and #kew.playerlist == 0 then kew.timer = kew.phases[1].length end displayTitleToGroup(kew.playerlist,"Game starting!") displayTimeToGroup(kew.playerlist,minutes,seconds) --show countdown elseif kew.phase == 2 then --playing phase if #kew.playerlist == 0 then timer = 0 end -- finish if all players quit -- do vocab logic local victory = updatePlayedZone(kew.buildzone) --currently victory updatePlayedZone returns always false -- displayTimeToGroup(kew.playerlist,minutes,seconds) elseif kew.phase == 3 then --end phase displayTitleToGroup(kew.playerlist,"Use HOMECOMER to return") --displayTimeToGroup(kew.playerlist,minutes,seconds) end end end --this runs after a buildzone is completed --it should tally structure types and set scoreboard highscores --it also rewards all participants with more played score function processHighscores(kew) local buildzone = kew.buildzone --add score to players who finished this game for _,player in ipairs(kew.playerlist) do commands.async.scoreboard("players","add",player.name,"played",1) end end --function to export a buildzone detail once it is complete --requires a kew so it can access the playerlist local function exportKewData(kew) local buildzone = kew.buildzone local saved = {} saved.position = { x=buildzone.x, y=buildzone.y, z=buildzone.z } local timestamp = math.floor(os.clock()) --saved.timeCompleted = timestamp saved.players = {} for _, player in ipairs(kew.playerlist) do table.insert(saved.players,player.name) end --saved.structures = buildzone.structures saved.buildings = buildzone.buildings saved.totals = tracker.tallyTable(buildzone.structures) --saved.highest = buildzone.highest saved.stats = { cityVersion = CITY_VERSION, height = buildzone.highest, densityIndex = math.floor(100*buildzone.filledSlots/49), -- the density index is made from built area (filledSlots) over the ground area (7x7 slots = 49) greenIndex = math.floor(100*buildzone.greenSlots/49), --the green index is made from green area (greenSlots) over the ground area (7x7 slots = 49) variety = tablelength(buildzone.variety), timeCompleted = timestamp, gameLength = GAME_LENGTH } fs.makeDir("/records") local file = fs.open("/records/"..timestamp.."at"..buildzone.x.."_"..buildzone.z..".yaml","w") file.write(json.encodePretty(saved)) file.close() end --this code runs ONCE at the end of each phase --what actually happens is specific to which phase the --particular kew is in. function doPhaseEnds(game) for i,kew in ipairs(game.queues) do if kew.timer <= 0 then if kew.phase == 1 then --waiting phase ends goto play phase moveBuildzone(kew.buildzone,game.builds) teleportToZone(kew.buildzone,kew.playerlist,"Your game has started! BUILD A HOUSE!", "DE: TELEPORTED: Your game has started.")--teleport selected players cleanBuildzone(kew.buildzone) prepareBuildzone(kew.buildzone)--prepare build zone giveItems(kew.playerlist,STARTING_ITEMS) --give starting items displayTitle(kew.buildzone.selector,"BUILD!") kew.victory = false --displayTime(kew.buildzone.selector,0,0) kew.phase = 2 kew.timer = kew.phases[2].length elseif kew.phase == 2 then --playing phase ends goto end phase processHighscores(kew) exportKewData(kew) cleanAfterVictory(kew.buildzone) kew.phase = 3 --displayTime(kew.buildzone.selector,0,0) kew.timer = kew.phases[3].length elseif kew.phase == 3 then --end phase ends goto waiting phase removePlayersFromKew(game,kew) kew.phase = 1 --displayTime(kew.buildzone.selector,0,0) kew.timer = kew.phases[1].length end end end end --Replaces everything that is needed to start the game. Does not rebuild the floor, or clear anything away. --based on the settings it creates a full grid, or a partial grid, or no grid --it also places the ring, although this is disabled for now function prepareBuildzone(buildzone) local bz = buildzone local x,y,z,w = bz.x,bz.y,bz.z,bz.w --commands.fill(x,y-1,z,x+w,y-1,z+w,BLOCKS.CAMP_FLOOR) fillRing(buildzone.x,buildzone.y,buildzone.z,buildzone.w,BLOCKS.CONSTRUCTION.block) if DO_GRID then for x=0,6 do for z=0,6 do local rand = math.random()*100 --local result, text = commands.testforblock(bz.x+(x*9)+4,bz.y-1,bz.z+(z*9)+4,BLOCKS.CAMP_FLOOR.block) if rand > GRID_HOLE_CHANCE then --and result then commands.async.setblock(bz.x+(x*9)+4,bz.y,bz.z+(z*9)+4,BLOCKS.DETECT.block,BLOCKS.DETECT.data,"replace","minecraft:air") 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) 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) --commands.async.setblock(bz.x+(x*9)+4,bz.y-1,bz.z+(z*9)+4,BLOCKS.CAMP_FLOOR.block) end end end end commands.async.setblock(buildzone.x,buildzone.y,buildzone.z,BLOCKS.CONSTRUCTION.block) end --deletes everything inside the buildzone function cleanBuildzone(buildzone) print("Cleaning buildzone") for h=0,VICTORY_HEIGHT+20 do commands.async.fill(buildzone.x,buildzone.y+h,buildzone.z,buildzone.x+buildzone.w,buildzone.y+h,buildzone.z+buildzone.w,"minecraft:air") end end --[[ --moves all players assigned to the queue into the waiting area for the provided game. --It also changes them to Adventure mode and clears their inventory function respawnPlayers(game,kew) 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", "DE: TELEPORTED: Your game ended so you have been returned to the Spawn Point") --put players back in spawn area for i,player in ipairs(kew.playerlist) do --table.insert(game.waitlist,player) respawnPlayer(player,"") end kew.playerlist = {} end --]] function removePlayersFromKew(game,kew) for _, player in ipairs(kew.playerlist) do --commands.tell(player.name,"Your game is over. Use your Heimkehrer to return to spawn") -- announce success in English commands.async.tellraw(player.name,'["",{"text":"TIME OUT! GAME COMPLETE! Use your HOMECOMER to return to spawn.","color":"white"}]') -- announce success in German commands.async.tellraw(player.name,'["",{"text":"DE: TIME OUT! GAME FINISHED!","color":"gold"}]') end kew.playerlist = {} end function respawnPlayer(playername,message) commands.tell(playername,message) commands.async.gamemode(2,playername) commands.async.clear(playername,"minecraft:wool") commands.async.clear(playername,"minecraft:stone_pickaxe") end function checkForPlayerInBuildzone(player,buildzone) local result,message = commands.testfor('@a[name='..player.name..','..buildzone.selector..']') return result end function checkForPlayerInWaitzone(player) local selector = "x="..WAITZONE.x..",y="..WAITZONE.y..",z="..WAITZONE.z..",dx="..WAITZONE.w..",dy=256,dz="..WAITZONE.l local result,message = commands.testfor('@a[name='..player.name..','..selector..']') return result end function checkPlayers(game) local selector = "x="..WAITZONE.x..",y="..WAITZONE.y..",z="..WAITZONE.z..",dx="..WAITZONE.w..",dy=256,dz="..WAITZONE.l local loggedIn = getAllPos('m=2,'..selector) --refresh waitlist game.waitlist = loggedIn --check currently playing players for l,kew in ipairs(game.queues) do for i,builder in ipairs(kew.playerlist) do local isPlaying = checkForPlayerInBuildzone(builder,kew.buildzone) --remove players who are already in kews from the waitlist for j, player in ipairs(loggedIn) do if player.name == builder.name then table.remove(loggedIn,j) end end --if the game is in progress and the player is not found then remove them from the gamekew if not isPlaying and kew.phase == 2 then --table.remove(kew.playerlist,i) --print("Removed "..builder.name.." from game in progress") end end end end --adds players who wait in the orange room to slots in waiting buildzones function allocateWaiters(game) --find free slots local freeslots = {} for i, kew in ipairs(game.queues) do if kew.phase == 1 and #kew.playerlist < kew.maxplayers then local slots = kew.maxplayers - #kew.playerlist for j=1,slots do table.insert(freeslots,kew) end end end --RE-ENABLE SECOND SHUFFLETABLE IF YOU WANT RANDOM PLAYER MATCHUPS shuffleTable(game.waitlist) --shuffleTable(freeslots) while #freeslots > 0 and #game.waitlist > 0 do local player = table.remove(game.waitlist,1) local freeslot = table.remove(freeslots,1).playerlist table.insert(freeslot,player) end end --PARTICLE FUNCTIONS --particles shown to player while their shape is being checked for match function searchParticle(x,y,z) commands.async.particle("fireworksSpark",x,y,z,0.01,3,0.01,0.01,100) end -- particles shown to player on successful vocab match function successParticle(x,y,z) commands.async.particle("happyVillager",x,y,z,2,2,2,1,1000) commands.async.playsound("random.levelup","@a",x,y,z,1,1.2) end --- particles shown to player on failed vocab match function failParticle(x,y,z) commands.async.particle("reddust",x,y,z,0.1,0.1,1.5,1,200) commands.async.particle("reddust",x,y,z,1.5,0.1,0.1,1,200) commands.async.playsound("random.bowhit","@a",x,y,z,1,0.8) end --makes sure that incoming check requests dont exist already function addToChecklist(player,buildzone) for _, detector in ipairs(buildzone.waitingForCheck) do if detector.x == player.x and detector.y == player.y and detector.z == player.z then return false end end table.insert(buildzone.waitingForCheck,player) return true end --removes all barrier blocks from a buildzone which are used to carve space in vocabs function cleanBarriers(buildzone) for h=0,200 do 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") end end --The main chunk of code which deals with stepping on detector blocks and reading the vocab function updatePlayedZone(buildzone) local victory = false local buildzoneSelector = buildzone.selector --get all players on diamond, add them to the list of things to check local detectLocations = getAllOnBlockType(BLOCKS.DETECT.block,buildzoneSelector) for _, player in ipairs(detectLocations) do addToChecklist(player,buildzone) end --DEAL WITH THE DETECTOR AT THE TOP OF THE LIST IF THERE IS ONE if #buildzone.waitingForCheck > 0 then --DO PARTICLE EFFECTS IF A DETECTING BLOCK THAT IS DETECTING for i,loc in ipairs(buildzone.waitingForCheck) do searchParticle(loc.x,loc.y+1,loc.z) end local totalResult = false local checked = table.remove(buildzone.waitingForCheck,1) local x,y,z,name = checked.x,checked.y,checked.z,checked.name for i,vocab in pairs(buildzone.vocab) do 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") if result then --clone in the correct vocab 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") if DEBUG_MODE then print(clonemes[1]) end commands.async.give(name,vocab.reward) -- announce vocab success in English local rewardType = 'nature' if vocab.rewardUrban then rewardType = 'urban' end --print(vocab.typeEN) --print(vocab.nameEN) --print(vocab.height) --print(vocab.slots) --print(vocab.greenSlots) --print(vocab.rewardCount) --print(rewardType) 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"}]') -- announce vocab success in German commands.async.tellraw(name,'["",{"text":"DE: You built a '..vocab.typeDE..' | '..vocab.nameDE.. ' , which is '..vocab.height..' meters tall and gives '..vocab.slots..' density points, '..vocab.greenSlots..' green points and '..vocab.rewardCount..' '..rewardType..' resource!","color":"gold"}]') --clear out barrier blocks cleanBarriers(buildzone) --ADD THE NEW STRUCTURE TO THE RECORDS table.insert(buildzone.structures,vocab.nameEN) ---CHANGE HERE to make it record the place of the vocab too x, y, z and vocab id local building = {id=vocab.id,xpos=x,ypos=y,zpos=z,name=vocab.nameEN,time=os.clock(),player=name} table.insert(buildzone.buildings, building) --if vocab.green then buildzone.greenSlots = buildzone.greenSlots + vocab.greenSlots --end buildzone.filledSlots = buildzone.filledSlots + vocab.slots local newHeight = y + vocab.height - buildzone.y-1 -- the Y coordinate of the highest block above the ground. Our world has its ground at 55 which is in buildzone.y, subtracting 1 to compensate for player height if newHeight > buildzone.highest then buildzone.highest = newHeight end -- count variety print("adding variety: "..vocab.id) local varietyId = vocab.id -- we use a variety id instead of the vocab id because vocab id 1,2,3,4 for example are all houses so it is the same variety --we add only one type of house, one type of green house, one type of garden and one type of extension and we skip the two risers if vocab.id == 2 or vocab.id == 3 or vocab.id == 4 then varietyId = 1 end-- only one type for the 4 different orientations of the house if vocab.id == 14 or vocab.id == 15 or vocab.id == 16 then varietyId = 13 end-- only one type for the 4 different orientations of the house extension if vocab.id == 26 or vocab.id == 27 or vocab.id == 28 then varietyId = 25 end-- only one type for the 4 different orientations of the house garden extension if vocab.id == 38 or vocab.id == 39 or vocab.id == 40 then varietyId = 37 end-- only one type for the 4 different orientations of the green roof house if varietyId ~= 17 and varietyId ~= 18 then --skip the two riser as they ar enot buildings if buildzone.variety[varietyId] then print("increasing existing item") buildzone.variety[varietyId] = buildzone.variety[varietyId] + 1 else print("adding new item") buildzone.variety[varietyId] = 1 end end --- CHECK FOR PERSONAL RECORDS --- check if the new structure is the highest --- CHANGE here to live detect the contribution of the new structure to the 4 goals and update them local personalbest = tracker.getScore(name,"highest") if personalbest.count < newHeight then --commands.async.tell(name,"You just topped your personal record for highest structure!") commands.async.scoreboard("players","add",name,"highest",1) -- announce success in English commands.async.tellraw(name,'["",{"text":"You just topped your personal record for highest neighbourhood!","color":"white"}]') -- announce success in German commands.async.tellraw(name,'["",{"text":"DE: You just topped your personal record for highest structure!","color":"gold"}]') end --- --- -- CHECK if placing the current structure would result in beating a server-wide record on the 4 goals --calculate total slots - FOR GOAL "DENSEST NEIGHBOURHOOD" local most = tracker.getScore("Densest_[points]","highscores") local Kint = math.floor(100 * buildzone.filledSlots / 49) -- Kint is the density index made from built area (filledSlots) over ground area (7x7 slots = 49) if Kint > most.count then commands.async.scoreboard("players","set","Densest_[points]","highscores",Kint) -- announce success in English commands.async.tellraw("@a",'["",{"text":"Great! '..name.. ' just topped the record for the DENSEST NEIGHBOURHOOD!","color":"white"}]') -- announce success in German commands.async.tellraw("@a",'["",{"text":"DE: wow! '..name.. ' just topped the record for the DENSEST NEIGHBOURHOOD!","color":"gold"}]') --commands.async.say("@a","The record for the Densest Neighbourhood has been topped!") end -- FOR THE GOAL "MOST DIVERSE NEIGHBOURHOOD" -- here we need to count how many varieties of buildings there are --local structures = tracker.tallyTable(buildzone.structures) -- this counts the variety of buildings in a game local mostDiverse = tracker.getScore("Most-Diverse_[out-of-26]","highscores") local typeCount = tablelength(buildzone.variety) print("variety count is: "..typeCount) if typeCount > mostDiverse.count then commands.async.scoreboard("players","set","Most-Diverse_[out-of-26]","highscores", typeCount) -- announce success in English commands.async.tellraw("@a",'["",{"text":"Wow! '..name.. ' just topped the record for the MOST DIVERSE NEIGHBOURHOOD!","color":"white"}]') -- announce success in German commands.async.tellraw("@a",'["",{"text":"DE: wow! '..name.. ' just topped the record for the MOST DIVERSE NEIGHBOURHOOD!","color":"gold"}]') --commands.async.say("@a","The record for the Most Diverse Neighbourhood has been topped!") end -- FOR THE GOAL "GREENEST NEIGHBOURHOOD" -- here we need to count the number of green vocabs local greenest = tracker.getScore("Greenest_[points]","highscores") local Gint = math.floor(100*buildzone.greenSlots/49) --Gint is the green index, made from green area (greenSlots) over ground area (7x7 slots = 49) if Gint > greenest.count then commands.async.scoreboard("players","set","Greenest_[points]","highscores",Gint) -- announce success in English commands.async.tellraw("@a",'["",{"text":"Awesome! '..name.. ' just topped the record for the GREENEST NEIGHBOURHOOD!","color":"white"}]') -- announce success in German commands.async.tellraw("@a",'["",{"text":"DE: Awesome! '..name.. ' just topped the record for GREENEST NEIGHBOURHOOD!","color":"gold"}]') ---commands.async.say("@a","The record for the Densest Neighbourhood has been topped!") end --calculate highest placement -- FOR THE GOAL "TALLEST NEIGHBOURHOOD" local highest = tracker.getScore("Tallest_[meters]","highscores") if buildzone.highest > highest.count then commands.async.scoreboard("players","set","Tallest_[meters]","highscores",buildzone.highest) -- announce success in English commands.async.tellraw("@a",'["",{"text":"Incredible! '..name..' just topped the record for TALLEST NEIGHBOURHOOD!","color":"white"}]') -- announce success in German commands.async.tellraw("@a",'["",{"text":"DE: Awesome! '..name..' just topped the record for TALLEST NEIGHBOURHOOD!","color":"gold"}]') --commands.async.say("@a","The record for the Tallest Negihbourhood has been topped!") end --increase the "how many structures did i build" score for the building player commands.async.scoreboard("players","add",name,"built",1) commands.async.scoreboard("players","add",name,"building_"..vocab.id,1) totalResult = true break end end if totalResult then --yey win, do a happy time successParticle(x,y,z) else --no vocab found so do a fail particle --announce in English commands.async.tellraw(name,'["",{"text":"The shape you have built does not match any shape in the catalogue, try a different one.","color":"red"}]') -- announce in German commands.async.tellraw(name,'["",{"text":"DE: The shape you have built does not match any shape in the catalogue, try a different one.","color":"gold"}]') failParticle(x,y-1,z) end end return victory end -- returns how many items are in a table/list function tablelength(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end --Display game information on the monitor function debugDisplay(game) monitor.clear() if blink then monitor.setCursorPos(1,1) monitor.setTextColor(colors.red) monitor.write("Running") monitor.setTextColor(colors.white) redstone.setOutput("top",true) blink = false else redstone.setOutput("top",false) blink = true end local line = 2 for i,kew in ipairs(game.queues) do monitor.setCursorPos(1,line) local minutes = string.format("%02d",math.floor(kew.timer/60)) local seconds = string.format("%02d",math.floor(kew.timer - (minutes*60))) monitor.write("Buildzone "..i.." | Phase: "..kew.phase.." | Time: "..minutes..":"..seconds) monitor.setCursorPos(1,line+1) for i,player in ipairs(kew.playerlist) do monitor.write(player.name.." ") end line = line +2 end monitor.setCursorPos(1,10) for i,player in ipairs(game.waitlist) do monitor.write(player.name.." ") end end --BEGIN RUNTIME CODE local blink = true local game = setup() while true do update(game) if monitor then debugDisplay(game) end commands.async.weather("clear",10000) local resetbutton = redstone.getInput("left") if resetbutton then print("reset!") for i,kew in ipairs(game.queues) do if kew.phase == 2 then kew.timer = 5 end end end sleep(2) end
Optional Paste Settings
Category:
None
Cryptocurrency
Cybersecurity
Fixit
Food
Gaming
Haiku
Help
History
Housing
Jokes
Legal
Money
Movies
Music
Pets
Photo
Science
Software
Source Code
Spirit
Sports
Travel
TV
Writing
Tags:
Syntax Highlighting:
None
Bash
C
C#
C++
CSS
HTML
JSON
Java
JavaScript
Lua
Markdown (PRO members only)
Objective C
PHP
Perl
Python
Ruby
Swift
4CS
6502 ACME Cross Assembler
6502 Kick Assembler
6502 TASM/64TASS
ABAP
AIMMS
ALGOL 68
APT Sources
ARM
ASM (NASM)
ASP
ActionScript
ActionScript 3
Ada
Apache Log
AppleScript
Arduino
Asymptote
AutoIt
Autohotkey
Avisynth
Awk
BASCOM AVR
BNF
BOO
Bash
Basic4GL
Batch
BibTeX
Blitz Basic
Blitz3D
BlitzMax
BrainFuck
C
C (WinAPI)
C Intermediate Language
C for Macs
C#
C++
C++ (WinAPI)
C++ (with Qt extensions)
C: Loadrunner
CAD DCL
CAD Lisp
CFDG
CMake
COBOL
CSS
Ceylon
ChaiScript
Chapel
Clojure
Clone C
Clone C++
CoffeeScript
ColdFusion
Cuesheet
D
DCL
DCPU-16
DCS
DIV
DOT
Dart
Delphi
Delphi Prism (Oxygene)
Diff
E
ECMAScript
EPC
Easytrieve
Eiffel
Email
Erlang
Euphoria
F#
FO Language
Falcon
Filemaker
Formula One
Fortran
FreeBasic
FreeSWITCH
GAMBAS
GDB
GDScript
Game Maker
Genero
Genie
GetText
Go
Godot GLSL
Groovy
GwBasic
HQ9 Plus
HTML
HTML 5
Haskell
Haxe
HicEst
IDL
INI file
INTERCAL
IO
ISPF Panel Definition
Icon
Inno Script
J
JCL
JSON
Java
Java 5
JavaScript
Julia
KSP (Kontakt Script)
KiXtart
Kotlin
LDIF
LLVM
LOL Code
LScript
Latex
Liberty BASIC
Linden Scripting
Lisp
Loco Basic
Logtalk
Lotus Formulas
Lotus Script
Lua
M68000 Assembler
MIX Assembler
MK-61/52
MPASM
MXML
MagikSF
Make
MapBasic
Markdown (PRO members only)
MatLab
Mercury
MetaPost
Modula 2
Modula 3
Motorola 68000 HiSoft Dev
MySQL
Nagios
NetRexx
Nginx
Nim
NullSoft Installer
OCaml
OCaml Brief
Oberon 2
Objeck Programming Langua
Objective C
Octave
Open Object Rexx
OpenBSD PACKET FILTER
OpenGL Shading
Openoffice BASIC
Oracle 11
Oracle 8
Oz
PARI/GP
PCRE
PHP
PHP Brief
PL/I
PL/SQL
POV-Ray
ParaSail
Pascal
Pawn
Per
Perl
Perl 6
Phix
Pic 16
Pike
Pixel Bender
PostScript
PostgreSQL
PowerBuilder
PowerShell
ProFTPd
Progress
Prolog
Properties
ProvideX
Puppet
PureBasic
PyCon
Python
Python for S60
QBasic
QML
R
RBScript
REBOL
REG
RPM Spec
Racket
Rails
Rexx
Robots
Roff Manpage
Ruby
Ruby Gnuplot
Rust
SAS
SCL
SPARK
SPARQL
SQF
SQL
SSH Config
Scala
Scheme
Scilab
SdlBasic
Smalltalk
Smarty
StandardML
StoneScript
SuperCollider
Swift
SystemVerilog
T-SQL
TCL
TeXgraph
Tera Term
TypeScript
TypoScript
UPC
Unicon
UnrealScript
Urbi
VB.NET
VBScript
VHDL
VIM
Vala
Vedit
VeriLog
Visual Pro Log
VisualBasic
VisualFoxPro
WHOIS
WhiteSpace
Winbatch
XBasic
XML
XPP
Xojo
Xorg Config
YAML
YARA
Z80 Assembler
ZXBasic
autoconf
jQuery
mIRC
newLISP
q/kdb+
thinBasic
Paste Expiration:
Never
Burn after read
10 Minutes
1 Hour
1 Day
1 Week
2 Weeks
1 Month
6 Months
1 Year
Paste Exposure:
Public
Unlisted
Private
Folder:
(members only)
Password
NEW
Enabled
Disabled
Burn after read
NEW
Paste Name / Title:
Create New Paste
Hello
Guest
Sign Up
or
Login
Sign in with Facebook
Sign in with Twitter
Sign in with Google
You are currently not logged in, this means you can not edit or delete anything you paste.
Sign Up
or
Login
Public Pastes
OoT rando seed 6/13
52 min ago | 202.05 KB
w
18 hours ago | 0.09 KB
[email protected]
- idiot sending fr...
19 hours ago | 1.35 KB
Untitled
23 hours ago | 0.03 KB
Checking in availability
1 day ago | 0.66 KB
TRMP TOKEN
1 day ago | 1.56 KB
Untitled
1 day ago | 0.16 KB
my-push Script
1 day ago | 0.19 KB
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the
Cookies Policy
.
OK, I Understand
Not a member of Pastebin yet?
Sign Up
, it unlocks many cool features!