Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -------------------------------
- -- /lib/CatalogueSlot ---------
- -------------------------------
- --- This package keeps functions that deal with the creation, drawing
- -- of catalogue slots containing a key and an element
- local slot = {} -- the local table to contain the function
- catalogue = slot -- the public API in the form of a table
- -------------------------------
- --- PRIVATE FUNCTIONS ---------
- -------------------------------
- --- A catalogue slot constructor. Enforces some data structure
- local function newCatalogueSlot(id, key_box, gridcellSize)
- local nvz = {}
- nvz.id = id
- nvz.grid_cell_size = gridcellSize
- nvz.key = key_box
- nvz.element = box(
- key_box.corner_x - key_box.size_x - gridcellSize, key_box.corner_y, key_box.corner_z,
- key_box.size_x, key_box.size_y, key_box.size_z
- )
- return nvz
- end
- --- Checks if the parameters defining the geometry of the catalogue layout have changed
- local function catalogueParametersChanged(game)
- local settings = game.settings
- local result = false
- if game.last_settings then
- local last_settings = game.last_settings
- debug.log("game has been run before - will compare last with current settings for change in the catalogue")
- if settings.grid_cell_size ~= last_settings.grid_cell_size then result = true end
- if settings.catalogue_slot_count.x ~= last_settings.catalogue_slot_count.x or
- settings.catalogue_slot_count.z ~= last_settings.catalogue_slot_count.z
- then result = true end
- if settings.play_area_offset.x ~= last_settings.play_area_offset.x or
- settings.play_area_offset.z ~= last_settings.play_area_offset.z
- then
- result = true
- end
- if settings.trenches.WIDTH ~= last_settings.trenches.WIDTH or
- settings.trenches.DEPTH ~= last_settings.trenches.DEPTH
- then result = true end
- if settings.catalogue_slot_size.x ~= last_settings.catalogue_slot_size.x or
- settings.catalogue_slot_size.z ~= last_settings.catalogue_slot_size.z
- then result = true end
- if settings.catalogue_slot_offset ~= last_settings.catalogue_slot_offset then
- result = true
- end
- if result then
- debug.log("catalogue settings changed - need to regenerate catalogue in the minecraft world")
- else
- debug.log("catalogue settings did not change")
- end
- else
- debug.log("game has not been run before - need to generate catalogue in the minecraft world")
- result = true
- end
- return result
- end
- --- Checks the game object for settings
- -- TODO probably better in another package or handled in a different way
- local function checkGameObject(game)
- assert(game.settings, "checkGameObject(): argument [game] must have a .settings table")
- assert(game.blocks, "checkGameObject(): argument [game] must have a .blocks table")
- end
- --- Draws the plinth underneath all of the catalogue slots
- -- TODO get rid of the plinth, each slot should draw its own plinth
- local function drawCataloguePlinth(game)
- local settings = game.settings
- local blocks = game.blocks
- local x = settings.computer.x - (settings.play_area_offset.x - settings.catalogue_slot_offset) * settings.grid_cell_size - 1
- local y = settings.computer.y - 1
- local z = closestGridCoord(settings.computer.z, settings.grid_cell_size, settings.computer.z + settings.spawnzone_size/2)
- + (settings.play_area_offset.z - settings.catalogue_slot_offset )* settings.grid_cell_size + 1
- local dx = - 2 * settings.catalogue_slot_count.x * settings.grid_cell_size * ( settings.catalogue_slot_size.x + 1 )
- - settings.catalogue_slot_offset * settings.grid_cell_size * (settings.catalogue_slot_count.x+1) +1
- local dy = -y
- local dz = settings.catalogue_slot_count.z * settings.grid_cell_size * ( settings.catalogue_slot_size.z + 1 )
- + settings.catalogue_slot_offset * settings.grid_cell_size * (settings.catalogue_slot_count.z+1) -1
- local plinth_box = box ( x, y, z, dx, dy, dz )
- --fill the trench around the catalogue area with air
- mcset.fillBox( box_offset( box_top_layers(plinth_box, settings.trenches.DEPTH), settings.trenches.WIDTH, 0, settings.trenches.WIDTH), blocks.AIR )
- --fill the plinth of the catalogue area with dark grid blocks
- mcset.fillBox( plinth_box, blocks.DARK_GRID )
- --place the grid markers with White Grid
- mcset.fillGrid( box_top_layers(plinth_box, 1), settings.computer.x, settings.computer.y, settings.computer.z, settings.grid_cell_size, blocks.WHITE_GRID )
- end
- --- draws a catalogue slot in Minecraft
- local function drawSlot(slot, block_base, block_ring, block_key_area, block_grid_marker)
- local halfcell = math.floor(slot.grid_cell_size/2)
- local fullcell = slot.grid_cell_size
- --fill outer white grid ring around the key
- mcset.fillRing( box_offset( box_base(slot.key), halfcell+1,0,halfcell+1), block_ring )
- --fill outer white grid ring around the element
- mcset.fillRing( box_offset( box_base(slot.element), halfcell+1,0,halfcell+1), block_ring )
- --fill white grid ring around the element
- mcset.fillRing( box_offset( box_base(slot.element), 1,0,1), block_ring )
- --fill the area underneath the key
- mcset.fillBox( box_base(slot.key), block_key_area)
- --fill plug grid key
- mcset.fillGrid( box_base(slot.key), slot.key.base_center_x, slot.key.base_center_y, slot.key.base_center_z, fullcell, block_grid_marker )
- --fill plug grid element
- mcset.fillGrid( box_base(slot.element), slot.element.base_center_x, slot.element.base_center_y, slot.element.base_center_z, fullcell, block_grid_marker )
- end
- --- Moves the contents of a slot's key and element areas to a new location
- -- the locations are passed as a slot object from newCatalogueSlot()
- local function moveSlotContents(from_slot, to_slot)
- if from_slot and to_slot then
- mcset.moveBoxCenter(box_remove_base(from_slot.key), box_remove_base(to_slot.key))
- mcset.moveBoxCenter(box_remove_base(from_slot.element), box_remove_base(to_slot.element))
- return newCatalogueSlot(to_slot.id, to_slot.key, to_slot.gridcellSize)
- else
- return nil
- end
- end
- --- Moves a slot contents along the Y axis with delta_y blocks
- -- Returns an object representing the slot at its new location
- local function moveSlotContentsVertically(slot, delta_y)
- return moveSlotContents(slot, newCatalogueSlot(slot.id, box_move_y( slot.key, delta_y ), slot.gridcellSize))
- end
- local function setSlotDetector(slot, detector_block, dead_detector_block)
- local detector = mcget.testForBlock( slot.key.base_center_x,slot.key.base_center_y,slot.key.base_center_z, detector_block.block) -- the .variant is omited to allow variations of the detect block to be used as alternative detectors for now
- local blocker = mcget.testForBlock( slot.key.base_center_x,slot.key.base_center_y,slot.key.base_center_z, dead_detector_block)
- if not (detector or blocker) then
- mcset.setBlock(slot.key.base_center_x,slot.key.base_center_y,slot.key.base_center_z, detector_block)
- end
- end
- local function setSlotLabel(slot)
- mcset.placeLabel( (slot.key.base_center_x + slot.element.base_center_x)/2,slot.key.base_center_y,slot.key.base_center_z,'slot_#'..slot.id)
- end
- -------------------------------
- --- PUBLIC API ----------------
- -------------------------------
- --- A multi builder which uses the slot constructor to create a set of slots
- function slot.initCatalogue(settings)--,countX, countZ, sizeX, sizeZ)
- debug.log("initCatalogue() initializing the catalogue")
- local element = {
- --the sizes of any catalogue slot in minecraft blocks
- sizeX = settings.catalogue_slot_size.x * settings.grid_cell_size,
- sizeY = settings.element_height,
- sizeZ = settings.catalogue_slot_size.z * settings.grid_cell_size
- }
- local first_element = {
- x = settings.computer.x - settings.play_area_offset.x * settings.grid_cell_size - element.sizeX - math.floor(settings.grid_cell_size/2),
- y = settings.computer.y - 1,
- z = closestGridCoord(settings.computer.z, settings.grid_cell_size, settings.computer.z + settings.spawnzone_size/2)
- + settings.play_area_offset.z * settings.grid_cell_size + math.floor(settings.grid_cell_size/2) + 1
- }
- local x,y,z = first_element.x, first_element.y, first_element.z
- local result = {}
- local id = 1
- for i=0,settings.catalogue_slot_count.z-1 do
- for k=0, settings.catalogue_slot_count.x-1 do
- local xpos = x - k * ( settings.grid_cell_size * ( 2*settings.catalogue_slot_size.x + 2 + settings.catalogue_slot_offset))
- local ypos = y
- local zpos = z + i*( settings.grid_cell_size * ( settings.catalogue_slot_size.z + 1 + settings.catalogue_slot_offset))
- --print("adding an element",i,k)
- local nextSlot= newCatalogueSlot(
- id,
- box (xpos,ypos,zpos,
- element.sizeX, element.sizeY, element.sizeZ),
- settings.grid_cell_size
- )
- table.insert(result,nextSlot)
- id = id +1
- end
- end
- return result
- end
- function slot.drawCatalogue(game)
- checkGameObject(game)
- if catalogueParametersChanged(game) then
- debug.log("slot.drawCatalogueSlots(): building catalogue slots...")
- --draw the plinth under all slots
- --TODO remove the plinth and make each slot draw its own little plinth fragment
- drawCataloguePlinth(game)
- local blocks = game.blocks
- --loop the slots and ask them to draw themselves
- for i, slot in ipairs(game.catalogue) do
- drawSlot(slot, blocks.DARK_GRID, blocks.WHITE_GRID, blocks.WHITE_GRID, blocks.PLUG)
- end
- debug.log("Setting up catalogue elements")
- -- check if game has been played before and move the contents of the slots from their old location to the new one
- if game.last_settings then
- debug.log("Moving existing catalogue elements to their new locations")
- local old_slots = slot.initCatalogue(game.last_settings)
- --TODO use a function like map() or mapn() instead of for loops: https://en.wikibooks.org/wiki/Lua_Functional_Programming/Functions
- -- move the slot contents vertically first to so they dont overwrite each other when moving
- for i, new_slot in ipairs(game.catalogue) do
- old_slots[i] = moveSlotContentsVertically(old_slots[i], old_slots[i].key.size_y)
- os.sleep(1) -- wait for the server to catch up TODO this should be in the fillBox() function
- end
- -- move slot contents to their new locations
- for i, new_slot in ipairs(game.catalogue) do
- moveSlotContents(old_slots[i], new_slot)
- os.sleep(1) -- wait for the server to catch up
- end
- end
- -- number the slots and make sure they have detector or dead_detector blocks in the key center
- debug.log("Labeling catalogue elements")
- mcset.removeAllLabels() --clean up labels from slots from previous game runs
- for i,slot in ipairs(game.catalogue) do
- setSlotDetector(slot, blocks.DETECT, blocks.DETECT_DEAD)
- --label the slot in the world with its number
- setSlotLabel(slot)
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement