Module:Test/lib/util

From RimWorld Wiki
< Module:Test
Revision as of 14:45, 9 May 2021 by Dr. Strangelove (talk | contribs) (merged util with diet)
Jump to navigation Jump to search

local util = {}

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

util.table = {}

-- 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
    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

----------
-- diet --
----------

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

return util -- return module