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

From RimWorld Wiki
Jump to navigation Jump to search
(merged util with diet)
 
(5 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 foodType.None then
 
      return "Never eats"
 
  end
 
  if foodType.Tree then
 
      return "Dendrovorous"
 
  end
 
  if foodType.Meat then
 
      if foodType.VegetableOrFruit or foodType.Plant then
 
          return "Omnivorous"
 
      end
 
      return "Carnivorous"
 
  end
 
  if 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