Advertisement
antonsavov

WIP CatalogueSlot

Jan 4th, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.59 KB | None | 0 0
  1. -------------------------------
  2. -- /lib/CatalogueSlot ---------
  3. -------------------------------
  4. --- This package keeps functions that deal with the creation, drawing
  5. -- of catalogue slots containing a key and an element
  6.  
  7. local slot = {} -- the local table to contain the function
  8. catalogue = slot -- the public API in the form of a table
  9.  
  10. -------------------------------
  11. --- PRIVATE FUNCTIONS ---------
  12. -------------------------------
  13.  
  14. --- A catalogue slot constructor. Enforces some data structure
  15. local function newCatalogueSlot(id, key_box, gridcellSize)
  16.     local nvz = {}
  17.     nvz.id = id
  18.     nvz.grid_cell_size = gridcellSize
  19.     nvz.key = key_box
  20.     nvz.element = box(
  21.         key_box.corner_x - key_box.size_x - gridcellSize, key_box.corner_y, key_box.corner_z,
  22.         key_box.size_x, key_box.size_y, key_box.size_z
  23.     )
  24.     return nvz 
  25. end
  26.  
  27. --- Checks if the parameters defining the geometry of the catalogue layout have changed
  28. local function catalogueParametersChanged(game)
  29.     local settings = game.settings
  30.     local result = false
  31.     if game.last_settings then
  32.         local last_settings = game.last_settings
  33.        
  34.         debug.log("game has been run before - will compare last with current settings for change in the catalogue")
  35.        
  36.         if settings.grid_cell_size ~= last_settings.grid_cell_size then result = true end
  37.        
  38.         if settings.catalogue_slot_count.x ~= last_settings.catalogue_slot_count.x or
  39.             settings.catalogue_slot_count.z ~= last_settings.catalogue_slot_count.z
  40.             then result = true end
  41.            
  42.         if settings.play_area_offset.x ~= last_settings.play_area_offset.x or
  43.             settings.play_area_offset.z ~= last_settings.play_area_offset.z
  44.             then
  45.                 result = true
  46.             end
  47.        
  48.         if settings.trenches.WIDTH ~= last_settings.trenches.WIDTH or
  49.             settings.trenches.DEPTH ~= last_settings.trenches.DEPTH
  50.             then result = true  end
  51.            
  52.         if settings.catalogue_slot_size.x ~= last_settings.catalogue_slot_size.x or
  53.             settings.catalogue_slot_size.z ~= last_settings.catalogue_slot_size.z
  54.             then result = true end
  55.        
  56.         if settings.catalogue_slot_offset ~= last_settings.catalogue_slot_offset then
  57.             result = true
  58.         end
  59.        
  60.         if result then
  61.             debug.log("catalogue settings changed - need to regenerate catalogue in the minecraft world")
  62.         else
  63.             debug.log("catalogue settings did not change")
  64.         end
  65.     else
  66.         debug.log("game has not been run before - need to generate catalogue in the minecraft world")
  67.         result = true
  68.     end
  69.     return result
  70. end
  71.  
  72. --- Checks the game object for settings
  73. -- TODO probably better in another package or handled in a different way
  74. local function checkGameObject(game)
  75.     assert(game.settings, "checkGameObject(): argument [game] must have a .settings table")
  76.     assert(game.blocks, "checkGameObject(): argument [game] must have a .blocks table")
  77. end
  78.  
  79. --- Draws the plinth underneath all of the catalogue slots
  80. -- TODO get rid of the plinth, each slot should draw its own plinth
  81. local function drawCataloguePlinth(game)
  82.     local settings = game.settings
  83.     local blocks = game.blocks
  84.  
  85.     local x = settings.computer.x - (settings.play_area_offset.x - settings.catalogue_slot_offset) * settings.grid_cell_size - 1
  86.     local y = settings.computer.y - 1
  87.     local z = closestGridCoord(settings.computer.z, settings.grid_cell_size, settings.computer.z + settings.spawnzone_size/2)
  88.             + (settings.play_area_offset.z - settings.catalogue_slot_offset )* settings.grid_cell_size + 1
  89.     local dx = - 2 * settings.catalogue_slot_count.x * settings.grid_cell_size * ( settings.catalogue_slot_size.x + 1 )
  90.             - settings.catalogue_slot_offset * settings.grid_cell_size * (settings.catalogue_slot_count.x+1) +1
  91.     local dy = -y
  92.     local dz = settings.catalogue_slot_count.z * settings.grid_cell_size * ( settings.catalogue_slot_size.z + 1 )
  93.             + settings.catalogue_slot_offset * settings.grid_cell_size * (settings.catalogue_slot_count.z+1) -1
  94.    
  95.     local plinth_box = box ( x, y, z, dx, dy, dz )
  96.     --fill the trench around the catalogue area with air
  97.     mcset.fillBox( box_offset( box_top_layers(plinth_box, settings.trenches.DEPTH), settings.trenches.WIDTH, 0, settings.trenches.WIDTH), blocks.AIR )
  98.     --fill the plinth of the catalogue area with dark grid blocks
  99.     mcset.fillBox( plinth_box, blocks.DARK_GRID )
  100.     --place the grid markers with White Grid
  101.     mcset.fillGrid( box_top_layers(plinth_box, 1), settings.computer.x, settings.computer.y, settings.computer.z, settings.grid_cell_size, blocks.WHITE_GRID )
  102. end
  103.  
  104. --- draws a catalogue slot in Minecraft
  105. local function drawSlot(slot, block_base, block_ring, block_key_area, block_grid_marker)
  106.     local halfcell = math.floor(slot.grid_cell_size/2)
  107.     local fullcell = slot.grid_cell_size
  108.     --fill outer white grid ring around the key
  109.     mcset.fillRing( box_offset( box_base(slot.key), halfcell+1,0,halfcell+1), block_ring )
  110.     --fill outer white grid ring around the element
  111.     mcset.fillRing( box_offset( box_base(slot.element), halfcell+1,0,halfcell+1), block_ring )
  112.     --fill white grid ring around the element
  113.     mcset.fillRing( box_offset( box_base(slot.element), 1,0,1), block_ring )
  114.     --fill the area underneath the key
  115.     mcset.fillBox( box_base(slot.key), block_key_area)
  116.     --fill plug grid key
  117.     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 )
  118.     --fill plug grid element
  119.     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 )
  120. end
  121.  
  122. --- Moves the contents of a slot's key and element areas to a new location
  123. -- the locations are passed as a slot object from newCatalogueSlot()
  124. local function moveSlotContents(from_slot, to_slot)
  125.     if from_slot and to_slot then
  126.         mcset.moveBoxCenter(box_remove_base(from_slot.key), box_remove_base(to_slot.key))
  127.         mcset.moveBoxCenter(box_remove_base(from_slot.element), box_remove_base(to_slot.element))
  128.         return newCatalogueSlot(to_slot.id, to_slot.key, to_slot.gridcellSize)
  129.     else
  130.         return nil
  131.     end
  132. end
  133.  
  134. --- Moves a slot contents along the Y axis with delta_y blocks
  135. -- Returns an object representing the slot at its new location
  136. local function moveSlotContentsVertically(slot, delta_y)
  137.     return moveSlotContents(slot, newCatalogueSlot(slot.id, box_move_y( slot.key, delta_y ), slot.gridcellSize))
  138. end
  139.  
  140. local function setSlotDetector(slot, detector_block, dead_detector_block)
  141.     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
  142.     local blocker = mcget.testForBlock( slot.key.base_center_x,slot.key.base_center_y,slot.key.base_center_z, dead_detector_block)
  143.     if not (detector or blocker) then
  144.         mcset.setBlock(slot.key.base_center_x,slot.key.base_center_y,slot.key.base_center_z, detector_block)
  145.     end
  146. end
  147.  
  148. local function setSlotLabel(slot)
  149.     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)
  150. end
  151.  
  152. -------------------------------
  153. --- PUBLIC API ----------------
  154. -------------------------------
  155.  
  156. --- A multi builder which uses the slot constructor to create a set of slots
  157. function slot.initCatalogue(settings)--,countX, countZ, sizeX, sizeZ)
  158.     debug.log("initCatalogue() initializing the catalogue")
  159.     local element = {
  160.         --the sizes of any catalogue slot in minecraft blocks
  161.         sizeX = settings.catalogue_slot_size.x * settings.grid_cell_size,
  162.         sizeY = settings.element_height,
  163.         sizeZ = settings.catalogue_slot_size.z * settings.grid_cell_size
  164.     }
  165.     local first_element = {
  166.         x = settings.computer.x - settings.play_area_offset.x * settings.grid_cell_size - element.sizeX - math.floor(settings.grid_cell_size/2),
  167.         y = settings.computer.y - 1,
  168.         z = closestGridCoord(settings.computer.z, settings.grid_cell_size, settings.computer.z + settings.spawnzone_size/2)
  169.             + settings.play_area_offset.z * settings.grid_cell_size + math.floor(settings.grid_cell_size/2) + 1
  170.     }
  171.    
  172.     local x,y,z = first_element.x, first_element.y, first_element.z
  173.     local result = {}
  174.     local id = 1
  175.     for i=0,settings.catalogue_slot_count.z-1 do
  176.         for k=0, settings.catalogue_slot_count.x-1 do
  177.  
  178.             local xpos = x - k * ( settings.grid_cell_size * ( 2*settings.catalogue_slot_size.x + 2 + settings.catalogue_slot_offset))
  179.             local ypos = y
  180.             local zpos = z + i*( settings.grid_cell_size * ( settings.catalogue_slot_size.z + 1 + settings.catalogue_slot_offset))
  181.             --print("adding an element",i,k)
  182.             local nextSlot= newCatalogueSlot(
  183.                 id,
  184.                 box (xpos,ypos,zpos,
  185.                 element.sizeX, element.sizeY, element.sizeZ),
  186.                 settings.grid_cell_size
  187.             )
  188.             table.insert(result,nextSlot)
  189.             id = id +1
  190.         end
  191.     end
  192.     return result
  193. end
  194.  
  195.  
  196. function slot.drawCatalogue(game)
  197.     checkGameObject(game)
  198.     if catalogueParametersChanged(game) then
  199.         debug.log("slot.drawCatalogueSlots(): building catalogue slots...")
  200.         --draw the plinth under all slots
  201.         --TODO remove the plinth and make each slot draw its own little plinth fragment
  202.         drawCataloguePlinth(game)
  203.         local blocks = game.blocks
  204.         --loop the slots and ask them to draw themselves
  205.         for i, slot in ipairs(game.catalogue) do
  206.             drawSlot(slot, blocks.DARK_GRID, blocks.WHITE_GRID, blocks.WHITE_GRID, blocks.PLUG)
  207.         end
  208.         debug.log("Setting up catalogue elements")
  209.         -- check if game has been played before and move the contents of the slots from their old location to the new one
  210.         if game.last_settings then
  211.             debug.log("Moving existing catalogue elements to their new locations")
  212.             local old_slots = slot.initCatalogue(game.last_settings)
  213.             --TODO use a function like map() or mapn() instead of for loops: https://en.wikibooks.org/wiki/Lua_Functional_Programming/Functions
  214.             -- move the slot contents vertically first to so they dont overwrite each other when moving
  215.             for i, new_slot in ipairs(game.catalogue) do
  216.                 old_slots[i] = moveSlotContentsVertically(old_slots[i], old_slots[i].key.size_y)
  217.                 os.sleep(1) --  wait for the server to catch up TODO this should be in the fillBox() function
  218.             end
  219.             -- move slot contents to their new locations
  220.             for i, new_slot in ipairs(game.catalogue) do
  221.                 moveSlotContents(old_slots[i], new_slot)
  222.                 os.sleep(1) -- wait for the server to catch up
  223.             end
  224.         end
  225.         -- number the slots and make sure they have detector or dead_detector blocks in the key center
  226.         debug.log("Labeling catalogue elements")
  227.         mcset.removeAllLabels() --clean up labels from slots from previous game runs
  228.         for i,slot in ipairs(game.catalogue) do    
  229.             setSlotDetector(slot, blocks.DETECT, blocks.DETECT_DEAD)
  230.             --label the slot in the world with its number
  231.             setSlotLabel(slot)
  232.         end
  233.     end
  234. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement