function animate(animation) add(animations, animation, 1) animation.before() end function contains(haystack, needle) for h in all(haystack) do if needle == h then return true end end return false end function deepcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in next, orig, nil do copy[deepcopy(orig_key)] = deepcopy(orig_value) end setmetatable(copy, deepcopy(getmetatable(orig))) else -- number, string, boolean, etc copy = orig end return copy end function filter_list(arr, func) new = {} for old_index, v in ipairs(arr) do if func(v, old_index) then add(new, v) end end return new end function player_has(requirement, count, traits) if count == nil then count = 1 end output = {} for x in all(inventory) do if x.title == requirement or contains(x.tags, requirement) then for t in all(traits) do if not contains(x.traits, t) then goto continue end end if count == 1 then return x end add(output, x) ::continue:: end end if #output >= count then return filter_list(output, function(x,i) return i<=count end) end return nil end function make_item(blueprint) --if blueprint.description == nil then -- blueprint = library.item_blueprints[blueprint] --end item = deepcopy(blueprint) item.quality = flr(blueprint.quality_base + rnd(blueprint.quality_range)) if blueprint.tags then item.tags = deepcopy(blueprint.tags) else item.tags = {} end item.traits = {} if rnd(100) < blueprint.trait_chance then add(item.traits, rnd(blueprint.trait_pool)) end if rnd(100) < blueprint.trait_chance then local t = rnd(blueprint.trait_pool) if not contains(item.traits, t) then add(item.traits, t) end end return item end function at(trait, x,y) if (x < 0) return false if (x > trait[4]) return false if (y < 0) return false if (y > trait[4]) return false return mget(trait[2]+x, trait[3]+y) ~= 0 end function at_absolute(trait, x,y) return at(trait.trait, x-trait.x, y-trait.y) end function overlaps(trait1, trait2) t1_width = trait1.trait[4] t1_height = trait1.trait[5] for i=0,(t1_width-1) do for j=0,(t1_height-1) do x = trait1.x + i y = trait1.y + j if at_absolute(trait1, x, y) and at_absolute(trait2, x, y) then return true end end end return false end function change_screen(new_screen) prev_screen = current_screen if new_screen.before ~= nil then new_screen.before() end current_screen = new_screen end -- add newlines to a string to fit it into lines. function wrap(str, line_length) -- thanks to https://stackoverflow.com/questions/17586/best-word-wrap-algorithm, i did not feel like thinking this out myself words = split(str, " ", false) output = "" local current_line_length = 0 for w in all(words) do while sub(w, 1, 1) == "\n" do output = output .. "\n" current_line_length = 0 w = sub(w, 2) end if current_line_length + #w > line_length then if current_line_length > 0 then output = output .. "\n" current_line_length = 0 end end output = output .. w .. " " current_line_length += #w + 1 end return output end