Skip to content

Instantly share code, notes, and snippets.

@andrewandrepowell
Last active September 19, 2020 06:44
Show Gist options
  • Save andrewandrepowell/10636a467ee9f8e9070979a577868247 to your computer and use it in GitHub Desktop.
Save andrewandrepowell/10636a467ee9f8e9070979a577868247 to your computer and use it in GitHub Desktop.
Beginnings of Dual Universe scripting. Will become more organized later.
--
Item = {
-- Create a new Item.
new = function(name)
name = name or "none"
assert(type(name)=="string")
return {
name = name,
ingredients = false,
produced = false,
production_list = false,
}
end,
-- Traverse through an Item's ingredients.
traverse = function(item)
assert(isinstance(item, Item.new()))
local table = {}
local function traverse(item)
table[#table+1] = item
if item.ingredients == false then
return
end
for index, ingredients_amount in pairs(item.ingredients) do
traverse(ingredients_amount[1])
end
end
traverse(item)
return table
end,
-- Retreive a set of all the ingredients.
ingredients = function (item, name_enable)
-- First determine the set of ingredients.
local table = {}
for _, ingredients in pairs(Item.traverse(item)) do
if table[ingredients]==nil then
table[ingredients] = 0
end
end
-- Next, determine the total amounts needed.
local function traverse(item, amount_needed)
if item.ingredients == false then
return
end
for i, ingredient_amount in pairs(item.ingredients) do
table[ingredient_amount[1]] = table[ingredient_amount[1]]+ingredient_amount[2]*amount_needed
traverse(ingredient_amount[1], ingredient_amount[2])
end
end
table[item] = 1
traverse(item, 1)
-- Change the table references to names if specified.
name_enable = name_enable or false
assert(type(name_enable)=="boolean")
if name_enable then
local table_name = {}
for ingredient, amount in pairs(table) do
table_name[ingredient.name] = amount
end
return table_name
end
return table
end,
-- Produce an empty production table.
production = function(item)
-- First determine the industry set.
local table = {}
local table_raw = {}
local ingredients = Item.traverse(item)
for _, ingredient in pairs(ingredients) do
if ingredient.production_list ~= false then
local production = ingredient.production_list[1] -- defaults to the first industry.
table[production] = {}
else
table_raw[ingredient] = true
end
end
-- Determine the ingredients that need to be produced by the industries.
for _, ingredient in pairs(ingredients) do
if ingredient.production_list ~= false then
local production = ingredient.production_list[1]
table[production][ingredient] = true
end
end
-- Return the production table.
local production_table = {table, table_raw}
return production_table
end,
-- Produce the production table with the ingredient amounts.
production_amount = function(item, name_enable)
local production_table = Item.production(item)
-- Determine the ingredient amounts needed to be produced.
local ingredients_amounts = Item.ingredients(item)
for production, ingredients in pairs(production_table[1]) do
for ingredient, _ in pairs(ingredients) do
production_table[1][production][ingredient] = ingredients_amounts[ingredient]
end
end
for ingredient, _ in pairs(production_table[2]) do
production_table[2][ingredient] = ingredients_amounts[ingredient]
end
-- Change the table references to names if specified.
name_enable = name_enable or false
assert(type(name_enable)=="boolean")
if name_enable then
local table_name = {{}, {}}
for production, ingredients in pairs(production_table[1]) do
table_name[1][production.name] = {}
for ingredient, amount in pairs(ingredients) do
table_name[1][production.name][ingredient.name] = amount
end
end
for ingredient, amount in pairs(production_table[2]) do
table_name[2][ingredient.name] = amount
end
return table_name
end
return production_table
end,
production_tree = function(item, name_enable)
-- Generate node table for each production and ingredient pair in
-- the production table.
local production_table = Item.production(item)
for production, ingredients in pairs(production_table[1]) do
for ingredient, _ in pairs(ingredients) do
local node_table = {}
local ingredients0 = ingredient.ingredients
for _, ingredient_amount0 in pairs(ingredients0) do
local ingredient0 = ingredient_amount0[1]
local production0 = false
if ingredient0.production_list~=false then
production0 = ingredient0.production_list[1]
end
node_table[#node_table+1] = {production0, ingredient0}
end
production_table[1][production][ingredient] = node_table
end
end
-- Change the table references to names if specified.
name_enable = name_enable or false
assert(type(name_enable)=="boolean")
if name_enable then
local table_name = {{}, {}}
for production, ingredients in pairs(production_table[1]) do
table_name[1][production.name] = {}
for ingredient, node_table in pairs(ingredients) do
table_name[1][production.name][ingredient.name] = {}
for index, production_ingredient in pairs(node_table) do
local production_name = false
if production_ingredient[1] then
production_name = production_ingredient[1].name
end
table_name[1][production.name][ingredient.name][index] = {
production_name,
production_ingredient[2].name}
end
end
end
for ingredient, amount in pairs(production_table[2]) do
table_name[2][ingredient.name] = amount
end
return table_name
end
return production_table
end
}
Design = {
Container = {
MAX_CONNECTIONS = 10,
new = function(name)
if name~=nil then
assert(type(name)=="string")
end
return {
name = name or "no_name",
ingredients = {},
inputs = {},
outputs = {}
}
end,
add_ingredient = function(container, ingredient)
assert(isinstance(container, Design.Container.new()))
assert(isinstance(ingredient, Item.new()))
container.ingredients[#container.ingredients+1] = ingredient
end,
print_ingredients = function(container)
assert(isinstance(container, Design.Container.new()))
for _, ingredient in pairs(container.ingredients) do
print(container.name .. ": ingredient=" .. ingredient.name)
end
end,
},
Industry = {
MAX_INPUTS = 4,
new = function(production, ingredient)
if ingredient~=nil then
assert(production==nil or isinstance(production, Item.new()))
assert(ingredient==nil or isinstance(ingredient, Item.new()))
local found = false
for _, production0 in pairs(ingredient.production_list) do
if production0==production then
found = true
end
if found==false then
assert(false, "ingredient not associated with production")
end
end
end
return {
production = production or false,
ingredient = ingredient or false,
inputs = {},
output = false
}
end,
},
new = function()
return {
nodes = {}
}
end,
connect = function(design, obj0, obj1)
assert(isinstance(design, Design.new()))
-- Container connected to Industry.
if isinstance(obj0, Design.Container.new()) and isinstance(obj1, Design.Industry.new()) then
-- Verify connections.
assert(#obj0.outputs<Design.Container.MAX_CONNECTIONS, "obj0 has too many outputs")
assert(#obj1.inputs<Design.Industry.MAX_INPUTS, "obj1 has too many inputs")
-- Perform connections.
obj0.outputs[#obj0.outputs+1] = obj1
obj1.inputs[#obj1.inputs+1] = obj0
-- Industry connected to Container.
elseif isinstance(obj0, Design.Industry.new()) and isinstance(obj1, Design.Container.new()) then
-- Verify connections.
assert(obj0.output==false, "obj0 has an output set")
assert(#obj1.inputs<Design.Container.MAX_CONNECTIONS, "obj1 has too many inputs")
-- Perform connections.
obj0.output = obj1
obj1.inputs[#obj1.inputs+1] = obj0
-- Update Container.
Design.Container.add_ingredient(obj1, obj0.ingredient)
else
assert(false, "connection failed")
end
-- Update design.
local found_obj0 = false
local found_obj1 = false
for _, node in pairs(design.nodes) do
if node==obj0 then
found_obj0 = true
end
if node==obj1 then
found_obj1 = true
end
end
if found_obj0==false then
design.nodes[#design.nodes+1] = obj0
end
if found_obj1==false then
design.nodes[#design.nodes+1] = obj1
end
end,
check = function(design)
assert(isinstance(design, Design.new()))
for _, node in pairs(design.nodes) do
if isinstance(node, Design.Industry.new()) then
-- Check and make sure the Industry is getting all of its ingredients.
for _, ingredient_amount in pairs(node.ingredient.ingredients) do
local ingredient = ingredient_amount[1]
local found = false
for _, container in pairs(node.inputs) do
for _, ingredient0 in pairs(container.ingredients) do
if ingredient==ingredient0 then
found = true
end
end
end
assert(found==true, "production that produces " .. node.ingredient.name .. " is missing ingredient " .. ingredient.name)
end
assert(#node.ingredient.ingredients>0, "production that produces " .. node.ingredient.name .. " is missing ingredients")
-- Check and make sure the same container isn't used as both an input and an output.
for _, input in pairs(node.inputs) do
assert(input~=node.output, "production that produces " .. node.ingredient.name .. " has an input the same as its output")
end
end
end
end,
print_ingredients_in_containers = function(design)
assert(isinstance(design, Design.new()))
for _, node in pairs(design.nodes) do
if isinstance(node, Design.Container.new()) then
Design.Container.print_ingredients(node)
end
end
end
}
function isinstance(obj0, obj1)
assert(type(obj0)=="table", "obj0 must be a table")
assert(type(obj1)=="table", "obj0 must be a table")
for member1, _ in pairs(obj1) do
local found = false
for member0, _ in pairs(obj0) do
if member0==member1 then
found = true
end
end
if found == false then
return false
end
end
return true
end
-- Craft list
bauxite = Item.new("bauxite")
coal = Item.new("coal")
hematite = Item.new("hematite")
quartz = Item.new("quartz")
pure_hydrogen = Item.new("pure_hydrogen")
pure_aluminum = Item.new("pure_aluminum")
pure_carbon = Item.new("pure_carbon")
pure_iron = Item.new("pure_iron")
pure_silicon = Item.new("pure_silicon")
silumin = Item.new("silumin")
basic_screw = Item.new("basic_screw")
basic_pipe = Item.new("basic_pipe")
basic_burner = Item.new("basic_burner")
smelter_m = Item.new("smelter_m")
refiner_m = Item.new("refiner_m")
basic_power_system = Item.new("basic_power_system")
al_fe_alloy = Item.new("al_fe_alloy")
basic_connector = Item.new("basic_connector")
electronics_industry_m = Item.new("electronics_industry_m")
basic_electronics = Item.new("basic_electronics")
polycarbonate_plastic = Item.new("polycarbonate_plastic")
chemical_industry_m = Item.new("chemical_industry_m")
assembly_line_m = Item.new("assembly_line_m")
basic_mobile_panel_m = Item.new("basic_mobile_panel_m")
metalwork_industry_m = Item.new("metalwork_industry_m")
basic_reinforced_frame_m = Item.new("basic_reinforced_frame_m")
assembly_line_s = Item.new("assembly_line_s")
basic_mobile_panel_s = Item.new("basic_mobile_panel_s")
basic_reinforced_frame_s = Item.new("basic_reinforced_frame_s")
steel = Item.new("steel")
basic_chemical_container_m = Item.new("basic_chemical_container_m")
basic_robotic_arm_m = Item.new("basic_robotic_arm_m")
basic_component = Item.new("basic_component")
atmospheric_engine_m = Item.new("atmospheric_engine_m")
basic_injector = Item.new("basic_injector")
_3d_printer_m = Item.new("3d_printer_m")
basic_combustion_chamber_m = Item.new("basic_combustion_chamber_m")
adjustor_m = Item.new("adjustor_s")
adjustor_m.ingredients = {
{basic_pipe, 6}, {basic_injector, 5},
{basic_gaz_cylinder_s, 1}, {basic_standard_frame, 1}}
adjustor_m.produced = 1
adjustor_m.production_list = {assembly_line_s}
basic_combustion_chamber_m.ingredients = {
{steel, 49},
{basic_pipe, 25}}
basic_combustion_chamber_m.produced = 1
basic_combustion_chamber_m.production_list = {metalwork_industry_m}
_3d_printer_m.ingredients = {
{basic_pipe, 36},
{basic_injector, 25},
{basic_robotic_arm_m, 1},
{basic_reinforced_frame_m, 1}}
_3d_printer_m.produced = 1
_3d_printer_m.production_list = {assembly_line_m}
basic_injector.ingredients = {
{polycarbonate_plastic, 6},
{basic_screw, 4}}
basic_injector.produced = 4
basic_injector.production_list = {_3d_printer_m}
atmospheric_engine_m.ingredients = {
{basic_screw, 36},
{basic_injector, 25},
{basic_combustion_chamber_m, 1},
{basic_reinforced_frame_m, 1}}
atmospheric_engine_m.produced = 1
atmospheric_engine_m.production_list = {assembly_line_m}
basic_component.ingredients = {{al_fe_alloy, 10}}
basic_component.produced = 10
basic_component.production_list = {electronics_industry_m}
basic_robotic_arm_m.ingredients = {{silumin, 49}, {basic_component, 25}}
basic_robotic_arm_m.produced = 1
basic_robotic_arm_m.production_list = {metalwork_industry_m}
basic_chemical_container_m.ingredients = {{silumin, 49}, {basic_screw, 25}}
basic_chemical_container_m.produced = 1
basic_chemical_container_m.production_list = {metalwork_industry_m}
steel.ingredients = {{pure_iron, 100}, {pure_carbon, 50}}
steel.produced = 75
steel.production_list = {smelter_m}
basic_reinforced_frame_s.ingredients = {{steel, 11}}
basic_reinforced_frame_s.produced = 1
basic_reinforced_frame_s.production_list = {metalwork_industry_m}
basic_mobile_panel_s.ingredients = {
{silumin, 7},
{basic_screw, 5}}
basic_mobile_panel_s.produced = 1
basic_mobile_panel_s.production_list = {metalwork_industry_m}
assembly_line_s.ingredients = {
{basic_screw, 6},
{basic_power_system, 5},
{basic_mobile_panel_s, 1},
{basic_reinforced_frame_s, 1}}
assembly_line_s.produced = 1
assembly_line_s.production_list = {assembly_line_s}
basic_reinforced_frame_m.ingredients = {{steel, 74}}
basic_reinforced_frame_m.produced = 1
basic_reinforced_frame_m.production_list = {metalwork_industry_m}
metalwork_industry_m.ingredients = {
{basic_pipe, 36},
{basic_power_system, 25},
{basic_mobile_panel_m, 1},
{basic_reinforced_frame_m, 1}}
metalwork_industry_m.produced = 1
metalwork_industry_m.production_list = {assembly_line_m}
basic_mobile_panel_m.ingredients = {
{silumin, 49},
{basic_screw, 25}}
basic_mobile_panel_m.produced = 1
basic_mobile_panel_m.production_list = {metalwork_industry_m}
assembly_line_m.ingredients = {
{basic_screw, 36},
{basic_power_system, 25},
{basic_mobile_panel_m, 1},
{basic_reinforced_frame_m, 1}}
assembly_line_m.produced = 1
assembly_line_m.production_list = {assembly_line_m, assembly_line_s}
chemical_industry_m.ingredients = {
{basic_pipe, 36},
{basic_power_system, 25}}
chemical_industry_m.produced = 1
chemical_industry_m.production_list = {assembly_line_m}
polycarbonate_plastic.ingredients = {
{pure_carbon, 100},
{pure_hydrogen, 50}}
polycarbonate_plastic.produced = 75
polycarbonate_plastic.production_list = {chemical_industry_m}
basic_electronics.ingredients = {
{polycarbonate_plastic, 6},
{basic_component, 4}}
basic_electronics.produced = 1
basic_electronics.production_list = {electronics_industry_m}
electronics_industry_m.ingredients = {
{basic_pipe, 36},
{basic_electronics, 25},
{basic_robotic_arm_m, 1},
{basic_reinforced_frame_m, 1}}
electronics_industry_m.produced = 1
electronics_industry_m.production_list = {assembly_line_m}
basic_connector.ingredients = {{al_fe_alloy, 10}}
basic_connector.produced = 10
basic_connector.production_list = {electronics_industry_m}
al_fe_alloy.ingredients = {
{pure_aluminum, 100},
{pure_iron, 50}}
al_fe_alloy.produced = 75
al_fe_alloy.production_list = {smelter_m}
basic_power_system.ingredients = {
{al_fe_alloy, 6},
{basic_connector, 4}}
basic_power_system.produced = 1
basic_power_system.production_list = {electronics_industry_m}
refiner_m.ingredients = {
{basic_pipe, 36},
{basic_power_system, 25},
{basic_chemical_container_m, 1},
{basic_reinforced_frame_m, 1}}
refiner_m.produced = 1
refiner_m.production_list = {assembly_line_m}
pure_aluminum.ingredients = {{bauxite, 65}}
pure_aluminum.produced = 45
pure_aluminum.production_list = {refiner_m}
pure_carbon.ingredients = {{coal, 65}}
pure_carbon.produced = 45
pure_carbon.production_list = {refiner_m}
pure_iron.ingredients = {{hematite, 65}}
pure_iron.produced = 45
pure_iron.production_list = {refiner_m}
pure_silicon.ingredients = {{quartz, 65}}
pure_silicon.produced = 45
pure_silicon.production_list = {refiner_m}
basic_screw.ingredients = {{steel, 10}}
basic_screw.produced = 10
basic_screw.production_list = {metalwork_industry_m}
basic_burner.ingredients = {{silumin, 6}, {basic_screw, 4}}
basic_burner.produced = 1
basic_burner.production_list = {metalwork_industry_m}
silumin.ingredients = {{pure_aluminum, 100}, {pure_silicon, 50}}
silumin.produced = 75
silumin.production_list = {smelter_m}
basic_pipe.ingredients = {{silumin, 10}}
basic_pipe.produced = 10
basic_pipe.production_list = {metalwork_industry_m}
smelter_m.ingredients = {
{basic_pipe, 36},
{basic_burner, 25},
{basic_chemical_container_m, 1},
{basic_reinforced_frame_m, 1}}
smelter_m.produced = 1
smelter_m.production_list = {assembly_line_m}
dump = require 'pl.pretty'.dump
-- Produce the production values
--dump(item_ingredients(metalwork_industry_m, true))
--dump(Item.production_tree(metalwork_industry_m, true))
--dump(item_production_amount(basic_reinforced_frame_m, true))
--dump(item_production_amount(smelter_m, true))
--dump(item_production_amount(metalwork_industry_m, true))
--dump(item_production_amount(electronics_industry_m, true))
--dump(item_production_amount(assembly_line_m, true))
--dump(item_production_amount(smelter_m, true))
--dump(Item.production_amount(_3d_printer_m, true))
--dump(item_production_tree(refiner_m, true))
--print(isinstance(Item.new(), Container(Item.new())))
-- Basic Pipe
if false then
dump(Item.production_tree(basic_pipe, true))
dump(Item.production_amount(basic_pipe, true))
local design = Design.new()
local c0 = Design.Container.new()
Design.Container.add_ingredient(c0, bauxite)
Design.Container.add_ingredient(c0, quartz)
local c1 = Design.Container.new()
local c2 = Design.Container.new()
local c3 = Design.Container.new()
local i0 = Design.Industry.new(refiner_m, pure_aluminum)
local i1 = Design.Industry.new(refiner_m, pure_silicon)
local i2 = Design.Industry.new(smelter_m, silumin)
local i3 = Design.Industry.new(metalwork_industry_m, basic_pipe)
Design.connect(design, c0, i0)
Design.connect(design, c0, i1)
Design.connect(design, i0, c1)
Design.connect(design, i1, c1)
Design.connect(design, c1, i2)
Design.connect(design, i2, c2)
Design.connect(design, c2, i3)
Design.connect(design, i3, c3)
Design.check(design)
end
-- 3D Printer
if true then
dump(Item.production_tree(_3d_printer_m, true))
dump(Item.production_amount(_3d_printer_m, true))
local function refiner_design(design, container_input)
assert(isinstance(design, Design.new()))
assert(isinstance(container_input, Design.Container.new()))
local i0 = Design.Industry.new(refiner_m, pure_aluminum)
local i1 = Design.Industry.new(refiner_m, pure_carbon)
local i2 = Design.Industry.new(refiner_m, pure_iron)
local i3 = Design.Industry.new(refiner_m, pure_silicon)
local c0 = Design.Container.new("c0_refiner")
Design.Container.add_ingredient(c0, pure_hydrogen)
Design.connect(design, container_input, i0)
Design.connect(design, container_input, i1)
Design.connect(design, container_input, i2)
Design.connect(design, container_input, i3)
Design.connect(design, i0, c0)
Design.connect(design, i1, c0)
Design.connect(design, i2, c0)
Design.connect(design, i3, c0)
return c0
end
local d = Design.new()
local i_swap = Design.Industry.new(assembly_line_m, _3d_printer_m)
local i_poly = Design.Industry.new(chemical_industry_m, polycarbonate_plastic)
local i_bpipe = Design.Industry.new(metalwork_industry_m, basic_pipe)
local i_bframe = Design.Industry.new(metalwork_industry_m, basic_reinforced_frame_m)
local i_barm = Design.Industry.new(metalwork_industry_m, basic_robotic_arm_m)
local i_bscrew = Design.Industry.new(metalwork_industry_m, basic_screw)
local i_binjector = Design.Industry.new(_3d_printer_m, basic_injector)
local i_bcomponent = Design.Industry.new(electronics_industry_m, basic_component)
local i_alloy = Design.Industry.new(smelter_m, al_fe_alloy)
local i_silumin = Design.Industry.new(smelter_m, silumin)
local i_steel = Design.Industry.new(smelter_m, steel)
local c0 = Design.Container.new("c0")
local c1 = Design.Container.new("c1")
local c2 = Design.Container.new("c2")
local c6 = Design.Container.new("c6")
Design.Container.add_ingredient(c0, bauxite)
Design.Container.add_ingredient(c0, coal)
Design.Container.add_ingredient(c0, hematite)
Design.Container.add_ingredient(c0, quartz)
local c4 = refiner_design(d, c0)
Design.connect(d, c4, i_poly)
Design.connect(d, c4, i_silumin)
Design.connect(d, c4, i_alloy)
Design.connect(d, c4, i_steel)
Design.connect(d, i_poly, c2)
Design.connect(d, i_silumin, c2)
Design.connect(d, i_alloy, c2)
Design.connect(d, i_steel, c2)
Design.connect(d, c2, i_bframe)
Design.connect(d, c2, i_barm)
Design.connect(d, c2, i_bcomponent)
Design.connect(d, c2, i_bpipe)
Design.connect(d, c2, i_bscrew)
Design.connect(d, c2, i_binjector)
Design.connect(d, i_bscrew, c6)
Design.connect(d, i_bcomponent, c6)
Design.connect(d, c6, i_barm)
Design.connect(d, c6, i_binjector)
Design.connect(d, i_binjector, c1)
Design.connect(d, i_barm, c1)
Design.connect(d, i_bframe, c1)
Design.connect(d, i_bpipe, c1)
Design.connect(d, c1, i_swap)
Design.connect(d, i_swap, c0)
Design.print_ingredients_in_containers(d)
Design.check(d)
end
--dump(c0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment