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(bp) --if bp.description == nil then -- bp = library.i_bps[bp] --end local i = deepcopy(bp) i.quality = flr(bp.quality_base + rnd(bp.quality_range)) if bp.tags then i.tags = deepcopy(bp.tags) else i.tags = {} end i.traits = {} if rnd(100) < bp.trait_chance then add(i.traits, rnd(bp.trait_pool)) end if rnd(100) < bp.trait_chance then local t = rnd(bp.trait_pool) if not contains(i.traits, t) then add(i.traits, t) end end return i end function at(trait, x,y) if x < 0 or x >= trait[4] or y < 0 or y >= trait[5] then return false end 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 local words = split(str, " ", false) local output = "" local c = 0 for w in all(words) do while sub(w, 1, 1) == "\n" do output = output .. "\n" c = 0 w = sub(w, 2) end if c + #w > line_length then if c > 0 then output = output .. "\n" c = 0 end end output = output .. w .. " " c += #w + 1 end return output end