grid_size = 8 grid_width = 6 grid_height = 6 grid_x = 14 grid_y = 34 c = { ing_slot=1, -- the slot in the recipe currently being modified, whether sselecting trait or ingredient ing_idx=1, -- the index into filtered ingredients of the current ingredient selection trait_slot=0, -- the trait sslot of the recipe we're modifying. x=0, y=0 -- x y coordinates in the puzzle grid for the current trait } center_glyph = 132 ingredients = {} -- traits which have been placed traits = {} choosing_ingredient = true placing_trait = false finalizing = false big_button = false final_trait_options = {} final_selected_traits = {} function crafting_before() center_glyph = rnd({132, 134, 164, 166}) c.x = 0 c.y = 0 c.ing_slot = 1 c.ing_idx = 1 c.trait_slot = 0 ingredients = {} traits = {} final_trait_options = {} choosing_ingredient = true placing_trait = false finalizing = false big_button = false end function crafting_update() if choosing_ingredient then crafting_choice_update() elseif placing_trait then crafting_place_update() elseif finalizing then crafting_finalize_update() end end function crafting_choice_update() requirement = current_recipe.ingredients[c.ing_slot] filtered_ingredients = filter_list( inventory, function(ing) return requirement == ing.title or contains(ing.tags, requirement) end ) current_ingredient = filtered_ingredients[c.ing_idx] if btnp(0) and c.ing_idx>1 then sfx(3) c.ing_idx -= 1 end if btnp(1) and c.ing_idx<#filtered_ingredients then sfx(3) c.ing_idx += 1 end if btnp(4) and current_ingredient ~= nil then -- lock in this ingredient and move on to moving traits arund add(ingredients, current_ingredient) if #current_ingredient.traits ~= 0 then -- if there are traits on tihs ingredient, move on to setting traits. choosing_ingredient = false placing_trait = true finalizing = false c.trait_slot = 1 c.ing_idx = 1 elseif #ingredients < #current_recipe.ingredients then -- if there are remaining ingredients to set, then we move to the next ingredient slot. choosing_ingredient = true placing_trait = false finalizing = false c.trait_slot = 0 c.ing_idx = 1 c.ing_slot += 1 else -- if there are no more ingredients to set, then we finalize. sfx(2) c.x, c.y = 0, 0 final_trait_options = filter_list(traits, function(x) return x.active end) choosing_ingredient = false placing_trait = false finalizing = true c.trait_slot = 0 c.ing_idx = 1 c.ing_slot = 1 end end if (btnp(5)) then -- delete the last ingredient from the ingredients list if #ingredients == 0 then change_screen(screen_recipe_list) else traits = filter_list( traits, function(set_trait) return set_trait.from_ingredient_slot ~= #ingredients end ) deli(ingredients) c.trait_slot = 0 if choosing_ingredient and c.ing_slot > 1 then c.ing_slot -= 1 end choosing_ingredient = true placing_trait = false end end end function crafting_place_update() current_ingredient = ingredients[c.ing_slot] current_trait = library.traits[current_ingredient.traits[c.trait_slot]] width = current_trait[4] height = current_trait[5] if btnp(0) and c.x>0 then c.x -= 1 end if btnp(1) and c.x+width < grid_width then c.x += 1 end if btnp(2) and c.y>0 then c.y -= 1 end if btnp(3) and c.y+height < grid_height then c.y += 1 end if btnp(4) then new_trait = {trait=current_trait, x=c.x, y=c.y, active=true, from_ingredient_slot=c.ing_slot} for idx, trait in ipairs(traits) do if overlaps(trait, new_trait) then traits[idx].active = false end end add(traits, new_trait) if c.trait_slot < #current_ingredient.traits then -- if there's more traits to set, then we should keep setting traits. choosing_ingredient = false placing_trait = true finalizing = false c.trait_slot += 1 elseif c.ing_slot < #current_recipe.ingredients then -- if there's more ingredients to set, then we move on to setting ingredients. choosing_ingredient = true placing_trait = false finalizing = false c.trait_slot = 0 c.ing_slot += 1 else -- if there's no more ingredients to set, then we move on to finalizing. sfx(2) c.x, c.y = 0, 0 final_trait_options = filter_list(traits, function(x) return x.active end) choosing_ingredient = false placing_trait = false finalizing = true c.trait_slot = 0 c.ing_slot = 1 end end if (btnp(5)) then undo_ingredient() end end function crafting_finalize_update() if #final_trait_options < 3 then big_button = true end if not big_button then newx, newy = c.x, c.y if btnp(0) then newx -= 1 end if btnp(1) then newx += 1 end if btnp(2) then newy -= 1 end if btnp(3) then newy += 1 end if (final_trait_options[2*newy + newx + 1] ~= nil) and newx <= 1 and newx >= 0 then c.x, c.y = newx, newy elseif btnp(3) and not (btnp(0) or btnp(1) or btnp(2)) then big_button = true end local i = 2*c.y + c.x + 1 if btnp(4) and not big_button and #final_selected_traits < 2 then if not contains(final_selected_traits, i) then add(final_selected_traits, i) end end --todo: go back (btnp5) else if btnp(2) and #final_trait_options > 2 then big_button = false end if btnp(4) then make_the_product() big_button = false end if btnp(5) and #final_trait_options < 3 then -- go back a step undo_ingredient() finalizing = false elseif btnp(5) then big_button = false end end end function make_the_product() local product = make_item(library.item_blueprints[current_recipe.result]) product.quality = quality() add(inventory, product) for x in all(ingredients) do del(inventory, x) end product.traits = {} if #final_trait_options < 3 then for t in all(final_trait_options) do add(product.traits, t.trait[1]) end else for i in all(final_selected_traits) do add(product.traits, final_trait_options[i].trait[1]) end end sfx(5) change_screen(screen_recipe_list) end function undo_ingredient() if #ingredients == 0 then change_screen(screen_recipe_list) else traits = filter_list( traits, function(set_trait) return set_trait.from_ingredient_slot ~= #ingredients end ) deli(ingredients) c.trait_slot = 0 if choosing_ingredient and c.ing_slot > 1 then c.ing_slot -= 1 end choosing_ingredient = true placing_trait = false end end function crafting_draw() cls() draw_background() draw_paper(30,8,140,140) draw_recipe_on_paper(current_recipe, 30, 8) draw_recipe_in_progress_on_paper(30, 8) -- puzzle grid including pieces draw_grid() if finalizing then if #final_trait_options > 2 then draw_paper(24, 10, 128-24-24, 128-10-10) color(highlight_text_color) print("pick two traits\nto keep!",32, 20) for i, trait in ipairs(final_trait_options) do xi, yi = (i-1)%2, (i+i%2-2)/2 x, y = 64-32+xi*32, 34+yi*8 if contains(final_selected_traits, i) then rect(x-2, y-2, x+30, y+6, 10) end if not big_button and xi == c.x and yi == c.y then rect(x-2, y-2, x+30, y+6, 0) end if contains(final_selected_traits, i) then color(highlight_text_color) else color(base_text_color) end print(trait.trait[1], x, y ) end --draw_paper(40, 76, 128-40-40, 12) color(highlight_text_color) if big_button then pal(9,0) else palt(12, true) end spr(128, 64-16, 72, 4,4) spr(center_glyph, 64-8, 80, 2, 2) pal() palt() if big_button then color(12) else color(highlight_text_color) end print("create!", 64-12, 108) else draw_paper(30, 30, 128-30-30, 128-30-30) pal(9,0) spr(128, 64-16, 60-16, 4,4) spr(center_glyph, 64-8, 60-8, 2, 2) pal() palt() if big_button then color(12) else color(highlight_text_color) end print("create!", 64-12, 80) end end end function draw_grid() map(0,0, grid_x,grid_y, grid_width+1,grid_height+1) for trait in all(traits) do if trait.active then map(trait.trait[2], trait.trait[3], (trait.x*grid_size)+grid_x, (trait.y*grid_size)+grid_y, trait.trait[4], trait.trait[5]) end end if (placing_trait) then trait = library.traits[ingredients[c.ing_slot].traits[c.trait_slot]] -- draw the currently selected trait into the grid map(trait[2], trait[3], (c.x*grid_size)+grid_x, (c.y*grid_size)+grid_y, trait[4], trait[5]) end end function draw_recipe_in_progress_on_paper(x, y) -- selected ingredients for i, ing in ipairs(ingredients) do draw_ingredient_listing(ing, x+40, y + 26*i) end color(blank_ingredient_outline_color) for i=(c.ing_slot+1),#current_recipe.ingredients do print(current_recipe.ingredients[i], x+46, y+2+26*i+9) end -- quality listing color(base_text_color) print("quality", x+2, y+12) print_quality(quality(), x+44, y+18) if (choosing_ingredient and c.ing_slot < #current_recipe.ingredients + 1) then -- draw a box around the ingredient we're choosing yc = y + 26*c.ing_slot xc = x+40 rect(xc, yc, xc+55, yc+26,10) spr(6, xc-8, yc+10) spr(7, xc+56, yc+10) if current_ingredient == nil then color(blank_ingredient_outline_color) print(current_recipe.ingredients[c.ing_slot], x+46, y+2+26*c.ing_slot+9) else -- draw the ingredient listing for the selected ingredient draw_ingredient_listing(current_ingredient, xc, yc) end elseif (placing_trait) then -- draw a marker for the trait we're picking yc = y + 26*c.ing_slot yc = 3+yc+c.trait_slot*6 xc = x+38 spr(8, xc, yc) end for i, t in ipairs(filter_list(traits, function(trait) return trait.active end)) do color(base_text_color) print(t.trait[1], x+5, y+78 + 8*i) end end function quality() local quality_sum = 0 for ing in all(ingredients) do quality_sum += ing.quality end if #ingredients > 1 then quality_sum = flr(quality_sum/#ingredients) else quality_sum = flr(quality_sum) end for trait in all(traits) do if trait.active then quality_sum += 5 end end return quality_sum end screen_crafting_raw = {before=crafting_before, draw=crafting_draw, update=crafting_update} screen_crafting = screen_crafting_raw if not testing then screen_crafting = screen_conversation({ {phoebe_portrait, [[when i craft, i pick ingredients one by one with left and right]]}, {phoebe_portrait, [[and press 🅾️ to lock them in before picking what traits to use]]}, {phoebe_portrait, [[trying to fit them into the grid, which increases the quality. ]]}, {phoebe_portrait, [[two traits from those still in the grid at the end are added to the product!]]}, {phoebe_portrait, [[but if you overlap a trait, it will be removed.]]}, {phoebe_portrait, [[i've even heard of some traits that combine to form others!]]} }, function() screen_crafting = screen_crafting_raw change_screen(screen_crafting) end, screen_crafting_raw) end