Difference between revisions of "Module:Test/lib/util"

From RimWorld Wiki
Jump to navigation Jump to search
("look before you leap")
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
if mw then
 +
  Search = Search or require("Module:Test/lib/search")
 +
else
 +
  Search = Search or require "lib/search"
 +
end
 +
 
local util = {}
 
local util = {}
  
Line 6: Line 12:
  
 
util.table = {}
 
util.table = {}
 +
 +
function util.table.check(tbl, ...)
 +
  local inside = tbl
 +
  for i,v in pairs(arg) do
 +
    if i ~= 'n' then
 +
      inside = Search.find(v, inside or {})
 +
    end
 +
  end
 +
  return inside and true
 +
end
 +
 +
function util.table.checkMultiple(tbl, filters)
 +
  local checked = false
 +
  for _,filter in ipairs(filters) do
 +
    if util.table.check(tbl, unpack(filter)) then
 +
      checked = true
 +
    else
 +
      return false
 +
    end
 +
  end
 +
  return checked
 +
end
 +
 +
function util.table.isIn(var, table)
 +
  assert(type(var) == 'nil', "isIn: Empty argument #1")
 +
  assert(type(table) == 'table', string.format("isIn: Bad argument #2 ('table' expected, got '%s'", type(table)))
 +
  for k,v in pairs(table) do
 +
    if var == k or var == v then
 +
      return true
 +
    end
 +
  end
 +
  return false
 +
end
  
 
-- procedure
 
-- procedure
Line 96: Line 135:
  
 
   for k, v in pairs(tbl) do
 
   for k, v in pairs(tbl) do
     formatting = string.rep("  ", indent) .. k .. ": "
+
     local formatting = string.rep("  ", indent) .. k .. ": "
 
     if type(v) == "table" then
 
     if type(v) == "table" then
 
       print(formatting)
 
       print(formatting)
Line 147: Line 186:
 
end
 
end
  
----------
+
function util.round(num, numDecimalPlaces)
-- diet --
+
   return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))
----------
 
 
 
util.diet = {}
 
 
 
util.diet.foodType = {
 
  None = true,
 
  VegetableOrFruit = true,
 
  Meat = true,
 
  Fluid = true,
 
  Corpse = true,
 
  Seed = true,
 
  AnimalProduct = true,
 
  Plant = true,
 
  Tree = true,
 
  Meal = true,
 
  Processed = true,
 
  Liquor = true,
 
  Kibble = true,
 
  VegetarianAnimal = {
 
    VegetableOrFruit = true,
 
    Seed = true,
 
    Meal = true,
 
    Processed = true,
 
    Liquor = true,
 
    Kibble = true
 
  },
 
  VegetarianRoughAnimal = {
 
    VegetableOrFruit = true,
 
    Seed = true,
 
    Plant = true,
 
    Meal = true,
 
    Processed = true,
 
    Liquor = true,
 
    Kibble = true
 
  },
 
  CarnivoreAnimal = {
 
    Meat = true,
 
    Corpse = true,
 
    Meal = true,
 
    Processed = true,
 
    Kibble = true
 
  },
 
  CarnivoreAnimalStrict = {
 
    Meat = true,
 
    Corpse = true
 
  },
 
  OmnivoreAnimal = {
 
    VegetableOrFruit = true,
 
    Meat = true,
 
    Corpse = true,
 
    Seed = true,
 
    Meal = true,
 
    Processed = true,
 
    Liquor = true,
 
    Kibble = true
 
  },
 
  OmnivoreRoughAnimal = {
 
    VegetableOrFruit = true,
 
    Meat = true,
 
    Corpse = true,
 
    Seed = true,
 
    Plant = true,
 
    Meal = true,
 
    Processed = true,
 
    Liquor = true,
 
    Kibble = true
 
  },
 
  DendrovoreAnimal = {
 
    VegetableOrFruit = true,
 
    Seed = true,
 
    Tree = true,
 
    Processed = true,
 
    Kibble = true
 
  },
 
  OvivoreAnimal = {
 
    AnimalProduct = true,
 
    Meal = true,
 
    Processed = true,
 
    Kibble = true
 
  },
 
  OmnivoreHuman = {
 
    VegetableOrFruit = true,
 
    Meat = true,
 
    Fluid = true,
 
    Corpse = true,
 
    Seed = true,
 
    AnimalProduct = true,
 
    Meal = true,
 
    Processed = true,
 
    Liquor = true,
 
    Kibble = true
 
  }
 
}
 
 
 
function util.diet.resolveDietCategory(foodType)
 
   if util.diet[foodType].None then
 
      return "Never eats"
 
  end
 
  if util.diet[foodType].Tree then
 
      return "Dendrovorous"
 
  end
 
  if util.diet[foodType].Meat then
 
      if util.diet[foodType].VegetableOrFruit or util.diet[foodType].Plant then
 
          return "Omnivorous"
 
      end
 
      return "Carnivorous"
 
  end
 
  if util.diet[foodType].AnimalProduct then
 
      return "Ovivorous"
 
  end
 
  return "Herbivorous"
 
 
end
 
end
  
 
return util -- return module
 
return util -- return module

Latest revision as of 21:00, 17 May 2021


if mw then
  Search = Search or require("Module:Test/lib/search")
else
  Search = Search or require "lib/search"
end

local util = {}

------------------------
-- table manipulation --
------------------------

util.table = {}

function util.table.check(tbl, ...)
  local inside = tbl
  for i,v in pairs(arg) do
    if i ~= 'n' then
      inside = Search.find(v, inside or {})
    end
  end
  return inside and true
end

function util.table.checkMultiple(tbl, filters)
  local checked = false
  for _,filter in ipairs(filters) do
    if util.table.check(tbl, unpack(filter)) then
      checked = true
    else
      return false
    end
  end
  return checked
end

function util.table.isIn(var, table)
  assert(type(var) == 'nil', "isIn: Empty argument #1")
  assert(type(table) == 'table', string.format("isIn: Bad argument #2 ('table' expected, got '%s'", type(table)))
  for k,v in pairs(table) do
    if var == k or var == v then
      return true
    end
  end
  return false
end

-- procedure
function util.table.overwrite(dest, source, ignoreKeys)
  ignoreKeys = ignoreKeys or {}

  for sK,sV in pairs(source) do
    local ignore = false

    for _,ignoredK in ipairs(ignoreKeys) do
      if sK == ignoredK then
        ignore = true
        break
      end
    end

    if not ignore then
      if type(sV) == "table" then
        if type(dest[sK]) == "table" then
          util.table.overwrite(dest[sK], sV, ignoreKeys)
        else
          dest[sK] = {}
          util.table.overwrite(dest[sK], sV, ignoreKeys)
        end
      else
        dest[sK] = sV
      end
    end
  end
end

--ref: https://gist.github.com/balaam/3122129
function util.table.reverse(tbl)
  local reversed_table = {}
  local length = #tbl

  for i,v in ipairs(tbl) do
      reversed_table[length + 1 - i] = v
  end

  for k,v in pairs(tbl) do
    if type(k) ~= 'number' then
      reversed_table[k] = v
    end
  end

  return reversed_table
end

--ref: http://lua-users.org/wiki/CopyTable
function util.table.shallowcopy(original_table)
  local orig_type = type(original_table)
  local copy
  if orig_type == 'table' then
      copy = {}
      for orig_key, orig_value in pairs(original_table) do
          copy[orig_key] = orig_value
      end
  else -- number, string, boolean, etc
      copy = original_table
  end
  return copy
end

-- this is not as strict as # so might bug out in extreme situations
-- needs love
function util.table.count(tbl, key_type)
  local length = 0;
  for k,v in pairs(tbl) do
    if key_type then
      if type(k) == key_type then
        length = length + 1
      end
    else
      length = length + 1
    end
  end
  return length
end

-- procedure
-- ref: https://gist.github.com/ripter/4270799
function util.table.tprint(tbl, indent)
  if not indent then indent = 0 end

  if type(tbl) ~= "table" then
    print(tbl)
    return 0
  end

  for k, v in pairs(tbl) do
    local formatting = string.rep("  ", indent) .. k .. ": "
    if type(v) == "table" then
      print(formatting)
      util.tprint(v, indent+1)
    elseif type(v) == 'boolean' then
      print(formatting .. tostring(v))
    else
      print(formatting .. v)
    end
  end
end

-- delimiter must be a single character
-- only for strings and numbers
function util.table.toCSVstring(tbl, delimiter)
  delimiter = delimiter or ","
  assert(#delimiter == 1 and type(delimiter) == 'toCSVstring', "toCSVstring: bad argument #2 (single character expected)")

  local csv = ""

  for k,v in pairs(tbl) do
    if type(v) == 'string' or type(v) == 'number' then
      csv = csv .. v .. delimiter
    else
      assert(false, "toCSVstring: can only handle numbers and strings")
    end
  end

  csv = string.sub(csv, 1, -2) -- remove final delimiter (works only for a single char)

  return csv
end

----------
-- misc --
----------

-- procedure
function util.hl(title, width)
  width = width or 80

  if type(title) == "string" then
    title = " " .. title .. " "
    local before = math.floor((width - #title) / 2)
    local after = width - before - #title
    print(string.rep("-", before) .. title .. string.rep("-", after))
  else
    print(string.rep("-", width))
  end
end

function util.round(num, numDecimalPlaces)
  return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))
end

return util -- return module