Add everything

This commit is contained in:
Simon Brodtmann 2025-08-31 17:45:38 +02:00
parent 77e4bc1106
commit f848e3cf98
1006 changed files with 39638 additions and 0 deletions

View file

@ -0,0 +1,40 @@
---------------------------------------------------------------------------------------------------
Version: 2.0.6
Date: 31.08.2025
Bug Fixes:
- Add missing subgroups (put icons in correct tab)
---------------------------------------------------------------------------------------------------
Version: 2.0.5
Date: 31.08.2025
Bug Fixes:
- Fixed Wood Underground pipe graphic (TheSAguy)
- Fixed Wood Underground pipe graphic (TheSAguy)
- Fixed Dart Turret ammo (TheSAguy)
Changes:
- Updated Rail Recipe (TheSAguy)
- Added Wooden Rail (TheSAguy)
- Updated some graphics (TheSAguy; BIG thanks to Snouz!)
---------------------------------------------------------------------------------------------------
Version: 2.0.4
Date: 28.07.2025
Bug Fixes:
- Fix Bio Boiler
---------------------------------------------------------------------------------------------------
Version: 2.0.3
Date: 13.07.2025
Bug Fixes:
- Fix several entities
---------------------------------------------------------------------------------------------------
Version: 2.0.2
Date: 07.07.2025
Bug Fixes:
- Fix compatibility with Krastorio2
Changes:
- Add compatibility with Space Age
- Add compatibility with Krastorio2 Spaced Out
---------------------------------------------------------------------------------------------------
Version: 2.0.1
Date: 06.07.2025
Bug Fixes:
- Fix locales
- Fix Musk floor

827
Bio_Industries_2/common.lua Normal file
View file

@ -0,0 +1,827 @@
require("util")
local compound_entities = require("prototypes.compound_entities.main_list")
return function(mod_name)
local common = {}
------------------------------------------------------------------------------------
-- Get mod name and path to mod
common.modName = script and script.mod_name or mod_name
common.modRoot = "__" .. common.modName .. "__"
------------------------------------------------------------------------------------
-- Greatly improved version check for mods (thanks to eradicator!)
common.Version = {}
do
local V = common.Version
local function parse_version(vstr) -- string "Major.Minor.Patch"
local err = function()
error('Invalid Version String: <' .. tostring(vstr) .. '>')
end
local r = { vstr:match('^(%d+)%.(%d+)%.(%d+)$') }
if #r ~= 3 then
err()
end
for i = 1, 3 do
r[i] = tonumber(r[i])
end
return r
end
V.gtr = function(verA, verB)
local a, b, c = unpack(parse_version(verA))
local x, y, z = unpack(parse_version(verB))
return (a > x) or (a == x and b > y) or (a == x and b == y and c > z)
end
local map = {
['='] = function(A, B) return not (V.gtr(A, B) or V.gtr(B, A)) end,
['>'] = V.gtr,
['!='] = function(A, B) return (V.gtr(A, B) or V.gtr(B, A)) end,
['<='] = function(A, B) return V.gtr(B, A) or (not V.gtr(A, B)) end,
['>='] = function(A, B) return V.gtr(A, B) or (not V.gtr(B, A)) end,
['~='] = function(A, B) return (V.gtr(A, B) or V.gtr(B, A)) end,
['<'] = function(A, B) return V.gtr(B, A) end,
}
common.check_version = function(mod_name, operator, need_version)
local mod_version = (mods and mods[mod_name]) or (script and script.active_mods[mod_name])
return map[operator](mod_version, need_version)
end
end
------------------------------------------------------------------------------------
-- Sane values for collision masks
-- Default: {"item-layer", "object-layer", "rail-layer", "floor-layer", "water-tile"}
common.RAIL_BRIDGE_MASK = { "object-layer", "consider-tile-transitions" }
-- "Transport Drones" removes "object-layer" from rails, so if bridges have only
-- {"object-layer"}, there collision mask will be empty, and they can be built even
-- over cliffs. So we need to add another layer to bridges ("floor-layer").
-- As of Factorio 1.1.0, rails need to have "rail-layer" in their mask. This will work
-- alright, but isn't available in earlier versions of Factorio, so we will use
-- "floor-layer" there instead.
local need = common.check_version("base", ">=", "1.1.0") and "rail-layer" or "floor-layer"
table.insert(common.RAIL_BRIDGE_MASK, need)
-- Rails use basically the same mask as rail bridges, ...
common.RAIL_MASK = util.table.deepcopy(common.RAIL_BRIDGE_MASK)
-- ... we just need to add some layers so our rails have the same mask as vanilla rails.
table.insert(common.RAIL_MASK, "item-layer")
table.insert(common.RAIL_MASK, "water-tile")
------------------------------------------------------------------------------------
-- Set maximum_wire_distance of Power-to-rail connectors
common.POWER_TO_RAIL_WIRE_DISTANCE = 4
------------------------------------------------------------------------------------
-- List of compound entities
-- Key: name of the base entity
-- tab: name of the global table where data of these entity are stored
-- hidden: table containing the hidden entities needed by this entity
-- (Key: name under which the hidden entity will be stored in the table;
-- Value: name of the entity that should be placed)
common.compound_entities = compound_entities.get_HE_list()
-- Map the short handles of hidden entities (e.g. "pole") to real prototype types
-- (e.g. "electric-pole")
common.HE_map = compound_entities.HE_map
-- Reverse lookup
common.HE_map_reverse = compound_entities.HE_map_reverse
------------------------------------------------------------------------------------
-- There may be trees for which we don't want to create variations. These patterns
-- are used to build a list of trees we want to ignore.
common.ignore_name_patterns = {
-- Ignore our own trees
"bio%-tree%-.+%-%d",
-- Tree prototypes created by "Robot Tree Farm" or "Tral's Robot Tree Farm"
"rtf%-.+%-%d+",
-- Tree prototypes created by "Industrial Revolution 2"
".*%-*ir2%-.+",
}
-- Get list of tree prototypes that we want to ignore
common.get_tree_ignore_list = function()
local ignore = {}
local trees = game and
prototypes.get_entity_filtered({ { filter = "type", type = "tree" } }) or
data.raw.tree
for tree_name, tree in pairs(trees) do
for p, pattern in ipairs(common.ignore_name_patterns) do
if tree_name:match(pattern) then
ignore[tree_name] = true
break
end
end
end
return ignore
end
-- 0.17.42/0.18.09 fixed a bug where musk floor was created for the force "enemy".
-- Because it didn't belong to any player, in map view the electric grid overlay wasn't
-- shown for musk floor. Somebody complained about seeing it now, so starting with version
-- 0.17.45/0.18.13, there is a setting to hide the overlay again. If it is set to "true",
-- a new force will be created that the hidden electric poles of musk floor belong to.
-- (UPDATE: 0.18.29 reversed the setting -- if active, tiles will now be visible in map
-- view, not hidden. The definition of UseMuskForce has been changed accordingly.)
common.MuskForceName = "BI-Musk_floor_general_owner"
common.UseMuskForce = not settings.startup["BI_Show_musk_floor_in_mapview"].value
------------------------------------------------------------------------------------
-- Enable writing to log file until startup options are set, so debugging output
-- from the start of a game session can be logged. This depends on a locally
-- installed dummy mod to allow debugging output during development without
-- spamming real users.
-- If the "_debug" dummy mod is active, debugging will always be on. If you don't
-- have this dummy mod but want to turn on logging anyway, set the default value
-- to "true"!
local default = false
common.is_debug = ((mods and mods["_debug"]) or
(script and script.active_mods["_debug"])) and
true or default
------------------------------------------------------------------------------------
-- DEBUGGING FUNCTIONS --
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
-- Output debugging text
common.writeDebug = function(msg, tab, print_line)
local args = {}
-- Use serpent.line instead of serpent.block if this is true!
local line = print_line and
(string.lower(print_line) == "line" or string.lower(print_line) == "l") and
true or false
if common.is_debug then
if type(tab) ~= "table" then
tab = { tab }
end
local v
for k = 1, #tab do
v = tab[k]
-- NIL
if v == nil then
args[#args + 1] = "NIL"
-- TABLE
elseif type(v) == "table" then
args[#args + 1] = line and serpent.line(table.deepcopy(v)) or
serpent.block(table.deepcopy(v))
-- OTHER VALUE
else
args[#args + 1] = v
end
end
if #args == 0 then
args[1] = "nil"
end
args.n = #args
-- Print the message text to log and game
log(string.format(tostring(msg), table.unpack(args)))
if game then
game.print(string.format(tostring(msg), table.unpack(args)))
end
end
end
------------------------------------------------------------------------------------
-- Simple helper to show a single value with descriptive text
common.show = function(desc, term)
if common.is_debug then
common.writeDebug(tostring(desc) .. ": %s", type(term) == "table" and { term } or term)
end
end
------------------------------------------------------------------------------------
-- Print "entityname (id)"
common.print_name_id = function(entity)
local id
local name = "unknown entity"
if entity and entity.valid then
-- Stickers don't have an index or unit_number!
id = (entity.type == "sticker" and entity.type) or
entity.unit_number or entity.type
name = entity.name
end
return string.format("%s (%s)", name, id or "nil")
end
------------------------------------------------------------------------------------
-- Print "entityname"
common.print_name = function(entity)
return entity and entity.valid and entity.name or ""
end
------------------------------------------------------------------------------------
-- Throw an error if a wrong argument has been passed to a function
common.arg_err = function(arg, arg_type)
error(string.format(
"Wrong argument! %s is not %s!",
(arg or "nil"), (arg_type and "a valid " .. arg_type or "valid")
)
)
end
------------------------------------------------------------------------------------
-- Rudimentary check of the arguments passed to a function
common.check_args = function(arg, arg_type, desc)
if not (arg and type(arg) == arg_type) then
game.print(type(arg) .. " = " .. arg_type)
common.arg_err(arg or "nil", desc or arg_type or "nil")
end
end
------------------------------------------------------------------------------------
-- MOD SPECIFIC --
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
-- Are tiles from Alien Biomes available? (Returns true or false)
common.AB_tiles = function()
local ret = false
if game then
local AB = prototypes.item["fertilizer"].place_as_tile_result.result.name
-- In data stage, place_as_tile is only changed to Alien Biomes tiles if
-- both "vegetation-green-grass-1" and "vegetation-green-grass-3" exist. Therefore,
-- we only need to check for one tile in the control stage.
ret = (AB == "vegetation-green-grass-3") and true or false
else
ret = data.raw.tile["vegetation-green-grass-1"] and
data.raw.tile["vegetation-green-grass-3"] and true or false
end
return ret
end
------------------------------------------------------------------------------------
-- Function for removing individual entities
common.remove_entity = function(entity)
if entity and entity.valid then
entity.destroy { raise_destroy = true }
end
end
------------------------------------------------------------------------------------
-- Function for removing invalid prototypes from list of compound entities
common.rebuild_compound_entity_list = function()
local f_name = "rebuild_compound_entity_list"
common.writeDebug("Entered function %s()", { f_name })
local ret = {}
for c_name, c_data in pairs(common.compound_entities) do
common.show("base_name", c_name)
common.show("data", c_data)
-- Is the base entity in the game?
if c_data.base and c_data.base.name and prototypes.entity[c_data.base.name] then
-- Make a copy of the compound-entity data
common.writeDebug("%s exists -- copying data", { c_name })
ret[c_name] = util.table.deepcopy(c_data)
-- Check hidden entities
for h_key, h_data in pairs(ret[c_name].hidden) do
common.writeDebug("h_key: %s\th_data: %s", { h_key, h_data })
-- Remove hidden entity if it doesn't exist
if not prototypes.entity[h_data.name] then
common.writeDebug("Removing %s (%s) from list of hidden entities!", { h_data.name, h_key })
ret[c_name].hidden[h_key] = nil
end
end
-- Clean table
else
local tab = c_data.tab
if tab then
-- Remove main table from global
common.writeDebug("Removing %s (%s obsolete entries)", { tab, #tab })
storage[tab] = nil
end
-- If this compound entity requires additional tables in global, initialize
-- them now!
local related_tables = c_data.add_global_tables
if related_tables then
for t, tab in ipairs(related_tables or {}) do
common.writeDebug("Removing storage[%s] (%s values)", { tab, table_size(storage[tab]) })
storage[tab] = nil
end
end
-- If this compound entity requires additional values in global, remove them!
local related_vars = c_data.add_global_values
if related_vars then
for var_name, value in pairs(related_vars or {}) do
common.writeDebug("Removing storage[%s] (was: %s)",
{ var_name, var_name and storage[var_name] or "nil" })
storage[var_name] = nil
end
end
end
end
common.show("ret", ret)
return ret
end
------------------------------------------------------------------------------------
-- Function to add all optional values for a compound entity to the table entry.
common.add_optional_data = function(base)
local f_name = "add_optional_data"
common.writeDebug("Entered function %s(%s)", { f_name, common.print_name_id(base) })
if not (base and base.valid and storage.compound_entities[base.name]) then
common.arg_err(base, "base of a compound entity")
end
-- Add optional values to global table
local data = storage.compound_entities[base.name]
common.show("data", data)
local tab = data.tab
common.show("tab", tab)
common.show("storage[tab]", storage[tab] or "nil")
local entry = storage[tab][base.unit_number]
for k, v in pairs(data.optional or {}) do
if entry[k] then
common.writeDebug("%s already exists: %s", { k, entry[k] })
else
entry[k] = v
common.writeDebug("Added data to %s: %s = %s", { common.print_name_id(base), k, v })
end
end
end
------------------------------------------------------------------------------------
-- Function for removing all parts of invalid compound entities
common.clean_global_compounds_table = function(entity_name)
local f_name = "clean_table"
common.writeDebug("Entered function %s(%s)", { f_name, entity_name or "nil" })
common.writeDebug("Entries in common.compound_entities[%s]: %s",
{ entity_name, table_size(storage.compound_entities[entity_name]) })
local entity_table = storage.compound_entities[entity_name]
common.show("entity_table", entity_table and entity_table.tab)
entity_table = entity_table and entity_table.tab and storage[entity_table.tab]
common.writeDebug("entity_table: %s", { entity_table }, "line")
local hidden_entities = storage.compound_entities[entity_name].hidden
common.show("hidden_entities", hidden_entities)
local removed = 0
-- Scan the whole table
for c, compound in pairs(entity_table) do
common.writeDebug("c: %s\tcompound: %s", { c, compound })
-- No or invalid base entity!
if not (compound.base and compound.base.valid) then
common.writeDebug("%s (%s) has no valid base entity -- removing entry!", { entity_name, c })
for h_name, h_entity in pairs(hidden_entities) do
common.writeDebug("Removing %s (%s)", { h_name, h_entity.name })
common.remove_entity(compound[h_name])
end
entity_table[c] = nil
removed = removed + 1
common.writeDebug("Removed %s %s", { entity_name, c })
end
end
common.show("Removed entities", removed)
common.show("Pruned list size", table_size(entity_table))
return removed
end
------------------------------------------------------------------------------------
-- Function to resore missing parts of compound entities
common.restore_missing_entities = function(entity_name)
local f_name = "restore_missing_entities"
common.writeDebug("Entered function %s(%s)", { f_name, entity_name or "nil" })
common.writeDebug("storage.compound_entities[%s]: %s entries",
{ entity_name, table_size(storage.compound_entities[entity_name]) })
local check = storage.compound_entities[entity_name]
local entity_table = check and storage[check.tab] or {}
local hidden_entities = check and check.hidden or {}
local checked = 0
local restored = 0
-- Scan the whole table
for c, compound in pairs(entity_table) do
-- Base entity is valid!
if (compound.base and compound.base.valid) then
common.writeDebug("%s is valid -- checking hidden entities!", { common.print_name_id(compound.base) })
for h_name, h_entity in pairs(hidden_entities) do
-- Hidden entity is missing
if compound[h_name] and compound[h_name].valid then
common.writeDebug("%s: OK", { h_name })
else
common.writeDebug("%s: MISSING!", { h_name })
common.create_entities(entity_table, compound.base, { [h_name] = h_entity.name })
restored = restored + 1
common.writeDebug("Created %s (%s) for %s",
{ h_name, h_entity.name, common.print_name_id(compound.base) })
end
end
checked = checked + 1
end
end
common.writeDebug("Checked %s compound entities", { checked })
common.writeDebug("Restored %s entities", { restored })
return { checked = checked, restored = restored }
end
------------------------------------------------------------------------------------
-- Function to find all unregistered compound entities of a particular type
common.register_in_compound_entity_tab = function(compound_name)
local f_name = "register_in_compound_entity_tab"
common.writeDebug("Entered function %s(%s)", { f_name, compound_name })
local cnt = 0
local h_cnt = 0
local data = storage.compound_entities[compound_name]
if not data then
common.arg_err(compound_name, "name of a compound entity")
end
local g_tab = storage[data.tab]
local found, h_found, created
-- Scan all surfaces
for s, surface in pairs(game.surfaces) do
-- Check the bases of all compound entities on the surface
found = surface.find_entities_filtered({ name = compound_name })
for b, base in ipairs(found) do
-- Base entity isn't registered yet!
if not g_tab[base.unit_number] then
common.writeDebug("Found unregistered entity: %s!", { common.print_name_id(base) })
-- Create an entry in the global table
g_tab[base.unit_number] = { base = base }
-- Add optional data to the table, if there are any
common.add_optional_data(base)
-- Check if it already has any hidden entities
for h_name, h_data in pairs(data.hidden) do
h_found = surface.find_entities_filtered({
name = h_data.name,
type = h_data.type,
position = common.offset_position(base.position, h_data.base_offset),
})
-- Check for multiple hidden entities of the same type in the same position!
if #h_found > 1 then
local cnt = 0
for duplicate = 2, #h_found do
h_found[duplicate].destroy({ raise_destroy = true })
cnt = cnt + 1
end
common.writeDebug("Removed %s duplicate entities (%s)!", { cnt, h_data.name })
end
-- There still is one hidden entity left. Add it to the table!
if next(h_found) then
common.writeDebug("Found %s -- adding it to the table.", { common.print_name_id(base) })
g_tab[base.unit_number][h_name] = h_found[1]
-- Create hidden entity! This will automatically add it to the table.
else
created = common.create_entities(g_tab, base, { [h_name] = h_data })
common.writeDebug("Created hidden %s: %s",
{ h_name, created and common.print_name_id(created) or "nil" })
h_cnt = h_cnt + 1
end
end
cnt = cnt + 1
end
end
end
common.writeDebug("Registered %s compound entities and created %s hidden entities", { cnt, h_cnt })
return cnt
end
------------------------------------------------------------------------------------
-- Function to find all unregistered compound entities
common.find_unregistered_entities = function()
local f_name = "find_unregistered_entities"
common.writeDebug("Entered function %s()", { f_name })
local cnt = 0
for compound_entity, c in pairs(storage.compound_entities) do
cnt = cnt + common.register_in_compound_entity_tab(compound_entity)
end
common.writeDebug("Registered %s compound entities.", { cnt })
return cnt
end
------------------------------------------------------------------------------------
-- Function to normalize positions
common.normalize_position = function(pos)
if pos and type(pos) == "table" and table_size(pos) == 2 then
local x = pos.x or pos[1]
local y = pos.y or pos[2]
if x and y and type(x) == "number" and type(y) == "number" then
return { x = x, y = y }
end
end
end
------------------------------------------------------------------------------------
-- Calculate the offset position of a hidden entity
common.offset_position = function(base_pos, offset)
common.check_args(base_pos, "table", "position")
offset = offset or { x = 0, y = 0 }
common.check_args(offset, "table", "position")
base_pos = common.normalize_position(base_pos)
offset = common.normalize_position(offset)
common.show("base_pos", base_pos)
common.show("offset", offset)
common.show("new", { x = base_pos.x + offset.x, y = base_pos.y + offset.y })
return { x = base_pos.x + offset.x, y = base_pos.y + offset.y }
end
------------------------------------------------------------------------------------
-- Check if argument is a valid surface
common.is_surface = function(surface)
local t = type(surface)
local result = false
if (t == "number" or t == "string") and game.surfaces[surface] and game.surfaces[surface].valid then
result = game.surfaces[surface]
elseif surface and surface.object_name == "LuaSurface" and surface.valid then
result = surface
end
return result
end
------------------------------------------------------------------------------------
-- Make hidden entities unminable and indestructible
local function make_unminable(entities)
for e, entity in ipairs(entities or {}) do
if entity.valid then
entity.minable = false
entity.destructible = false
end
end
end
--------------------------------------------------------------------
-- Create and register hidden entities
common.create_entities = function(g_table, base_entity, hidden_entities)
local f_name = "create_entities"
common.writeDebug("Entered function %s(%s, %s, %s)",
{ f_name, "g_table", base_entity, hidden_entities })
common.show("#g_table", g_table and table_size(g_table))
common.check_args(g_table, "table")
common.check_args(base_entity, "userdata")
if not base_entity.valid then
common.arg_err(base_entity, "base entity")
-- A table is required, but it may be empty! (This is needed for the
-- bio gardens, which only have a hidden pole if the "Easy Gardens"
-- setting is enabled.)
elseif not (hidden_entities and type(hidden_entities) == "table") then
common.arg_err(hidden_entities, "array of hidden-entity names")
end
local base_pos = common.normalize_position(base_entity.position) or
common.arg_err(position or "nil", "position")
local entity, offset, pos
-- Initialize entry in global table
g_table[base_entity.unit_number] = g_table[base_entity.unit_number] or {}
g_table[base_entity.unit_number].base = base_entity
-- Create hidden entities
local data
for key, tab in pairs(hidden_entities) do
common.writeDebug("key: %s\tname: %s", { key, tab })
data = storage.compound_entities[base_entity.name].hidden[key]
common.show("data", data)
entity = base_entity.surface.create_entity({
name = data.name,
type = data.type,
position = common.offset_position(base_pos, data.base_offset),
force = base_entity.force,
})
-- Raise the event manually, so we can pass on extra data!
script.raise_event(defines.events.script_raised_built, {
entity = entity,
base_entity = base_entity
})
-- Make hidden entity unminable/undestructible
make_unminable({ entity })
-- Add hidden entity to global table
g_table[base_entity.unit_number][key] = entity
end
-- Add optional values to global table
common.add_optional_data(base_entity)
common.writeDebug("g_table[%s]: %s", { base_entity.unit_number, g_table[base_entity.unit_number] })
end
--------------------------------------------------------------------
-- Make a list of the pole types that Bio gardens may connect to
common.get_garden_pole_connectors = function()
local ret
if common.get_startup_setting("BI_Easy_Bio_Gardens") then
common.writeDebug("\"Easy gardens\": Compiling list of poles they can connect to!")
ret = {}
local poles = prototypes.get_entity_filtered({
{ filter = "type", type = "electric-pole" },
{
filter = "name",
name = {
-- Poles named here will be ignored!
"bi-rail-power-hidden-pole",
"bi-musk-mat-hidden-pole",
"bi-bio-garden-hidden-pole"
},
invert = "true",
mode = "and"
}
})
for p, pole in pairs(poles) do
ret[#ret + 1] = pole.name
end
else
common.writeDebug("\"Easy gardens\": Not active -- nothing to do!")
end
return ret
end
--------------------------------------------------------------------
-- Connect hidden poles of Bio gardens!
-- (This function may be called for hidden poles that have not been
-- added to the table yet if the pole has just been built. In this
-- case, we pass on the new pole explicitly!)
common.connect_garden_pole = function(base, new_pole)
local compound_entity = storage.compound_entities["bi-bio-garden"]
local pole = storage[compound_entity.tab][base.unit_number] and
storage[compound_entity.tab][base.unit_number].pole or
new_pole
if pole and pole.valid and compound_entity.hidden and
compound_entity.hidden.pole and
compound_entity.hidden.pole.name then
local wire_reach = prototypes.entity[compound_entity.hidden.pole.name] and
prototypes.entity[compound_entity.hidden.pole.name].max_wire_distance
if not wire_reach then
error("Prototype for hidden pole of Bio gardens doesn't exist!")
end
pole.disconnect_neighbour()
-- Each pole can only have 5 connections. Let's connect to other hidden
-- poles first!
local connected
local neighbours = pole.surface.find_entities_filtered({
position = pole.position,
radius = wire_reach,
type = "electric-pole",
name = compound_entity.hidden.pole.name
})
common.writeDebug("Pole %g has %s neighbours", { pole.unit_number, #neighbours - 1 })
for n, neighbour in pairs(neighbours or {}) do
if pole ~= neighbour then
connected = pole.connect_neighbour(neighbour)
common.writeDebug("Connected pole %g to %s %g: %s",
{ pole.unit_number, neighbour.name, neighbour.unit_number, connected })
end
end
-- Look for other poles around this one
neighbours = pole.surface.find_entities_filtered({
position = pole.position,
radius = wire_reach,
type = "electric-pole",
name = storage.mod_settings.garden_pole_connectors,
})
common.writeDebug("Pole %g has %s neighbours", { pole.unit_number, #neighbours })
for n, neighbour in pairs(neighbours or {}) do
connected = pole.connect_neighbour(neighbour)
common.writeDebug("Connected pole %g to neighbour %s (%g): %s",
{ pole.unit_number, neighbour.name, neighbour.unit_number, connected })
end
end
end
--------------------------------------------------------------------
-- Connect hidden poles of powered rails -- this is also used in
-- migration scripts, so make it a function in common.lua!
-- (This function may be called for hidden poles that have not been
-- added to the table yet if the pole has just been built. In this
-- case, we pass on the new pole explicitly!)
common.connect_power_rail = function(base, new_pole)
local pole = storage.bi_power_rail_table[base.unit_number].pole or new_pole
if pole and pole.valid then
-- Remove all copper wires from new pole
pole.disconnect_neighbour()
common.writeDebug("Removed all wires from %s %g", { pole.name, pole.unit_number })
-- Look for connecting rails at front and back of the new rail
for s, side in ipairs({ "front", "back" }) do
common.writeDebug("Looking for rails at %s", { side })
local neighbour
-- Look in all three directions
for d, direction in ipairs({ "left", "straight", "right" }) do
common.writeDebug("Looking for rails in %s direction", { direction })
neighbour = base.get_connected_rail {
rail_direction = defines.rail_direction[side],
rail_connection_direction = defines.rail_connection_direction[direction]
}
common.writeDebug("Rail %s of %s (%s): %s (%s)",
{ direction, base.name, base.unit_number, (neighbour and neighbour.name or "nil"), (neighbour and neighbour.unit_number or "nil") })
-- Only make a connection if found rail is a powered rail
-- (We'll know it's the right type if we find it in our table!)
neighbour = neighbour and neighbour.valid and storage.bi_power_rail_table[neighbour.unit_number]
if neighbour and neighbour.pole and neighbour.pole.valid then
pole.connect_neighbour(neighbour.pole)
common.writeDebug("Connected poles!")
end
end
end
-- Look for Power-rail connectors
local connector = base.surface.find_entities_filtered {
position = base.position,
radius = common.POWER_TO_RAIL_WIRE_DISTANCE, -- maximum_wire_distance of Power-to-rail-connectors
name = "bi-power-to-rail-pole"
}
-- Connect to first Power-rail connector we've found
if connector and next(connector) then
pole.connect_neighbour(connector[1])
common.writeDebug("Connected " .. pole.name .. " (" .. pole.unit_number ..
") to " .. connector[1].name .. " (" .. connector[1].unit_number .. ")")
common.writeDebug("Connected %s (%g) to %s (%g)",
{ pole.name, pole.unit_number, connector[1].name, connector[1].unit_number })
end
common.writeDebug("Stored %s (%g) in global table", { base.name, base.unit_number })
end
end
------------------------------------------------------------------------------------
-- Get the value of a startup setting
common.get_startup_setting = function(setting_name)
return settings.startup[setting_name] and settings.startup[setting_name].value
end
------------------------------------------------------------------------------------
-- Add the "icons" property based on the value of "icon"
------------------------------------------------------------------------------------
common.BI_add_icons = function()
for tab_name, tab in pairs(data.raw) do
for proto_type_name, proto_type in pairs(data.raw[tab_name] or {}) do
if proto_type.BI_add_icon then
proto_type.icons = {
{
icon = proto_type.icon,
icon_size = proto_type.icon_size,
icon_mipmaps = proto_type.icon_mipmaps
}
}
proto_type.BI_add_icon = nil
common.writeDebug("Added \"icons\" property to data.raw[\"%s\"][\"%s\"]: %s",
{ tab_name, proto_type_name, proto_type.icons }, "line")
end
end
end
end
------------------------------------------------------------------------------------
-- END OF FILE
------------------------------------------------------------------------------------
return common
end

1043
Bio_Industries_2/control.lua Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,302 @@
BioInd.writeDebug("Entered control_arboretum.lua")
---Arboretum Stuff
local Event = require('__kry_stdlib__/stdlib/event/event').set_protected_mode(false)
-- If a recipe with NORMAL FERTILIZER is used, don't fertilize tiles set have "true"
-- set! (Fertile tiles set to true in this table can't be made more fertile with
-- normal fertilizer, and nothing should grow on the other tiles.)
local Terrain_Check_1 = {
["grass-1"] = true, -- Fertility: 100%
["grass-3"] = true, -- Fertility: 85%
["vegetation-green-grass-1"] = true, -- Fertility: 100%
["vegetation-green-grass-3"] = true, -- Fertility: 85%
}
-- If a recipe with ADVANCED FERTILIZER is used, don't fertilize tiles set have "true" set!
-- (Fertile tiles in this table can't be made more fertile, and nothing should grow on the
-- the others tiles!)
local Terrain_Check_2 = {
["grass-1"] = true, -- Fertility: 100%
["vegetation-green-grass-1"] = true, -- Fertility: 100%
}
local plant_radius = 75
-- Different tiles are used if AlienBiomes is active
local AB, terrain_name_g1, terrain_name_g3
-- OmniFluid replaces all fluids with items, so the arboretum won't have a fluidbox!
local function get_new_position(pos)
pos = BioInd.normalize_position(pos) or BioInd.arg_err("nil", position)
local xxx = math.random(-plant_radius, plant_radius)
local yyy = math.random(-plant_radius, plant_radius)
return { x = pos.x + xxx, y = pos.y + yyy }
end
-- Check that all ingredients are available!
local function check_ingredients(arboretum)
local recipe = arboretum.get_recipe()
if not recipe then
--game.print("No recipe set on arboretum")
return nil
end
--game.print("Recipe name: " .. recipe.name)
local need = storage.bi_arboretum_recipe_table[recipe.name]
if not need then
--game.print("No recipe data found for " .. recipe.name)
return nil
end
local function check(need, have)
for name, amount in pairs(need or {}) do
if not (have and have[name]) or (have[name] < amount) then
--game.print("Missing ingredient " .. name .. " (have " .. (have[name] or 0) .. " of " .. amount .. ")")
return false
end
end
return true
end
local inventory = arboretum.get_inventory(defines.inventory.assembling_machine_input)
local inv_contents_raw = inventory and inventory.get_contents() or {}
-- Check if inv_contents_raw is a map or list, convert if needed
local function is_map(t)
if type(t) ~= "table" then return false end
for k, v in pairs(t) do
if type(k) ~= "string" or type(v) ~= "number" then
return false
end
end
return true
end
local inv_contents
if is_map(inv_contents_raw) then
inv_contents = inv_contents_raw
else
-- Convert list of item stacks to map
inv_contents = {}
for _, item in pairs(inv_contents_raw) do
inv_contents[item.name] = (inv_contents[item.name] or 0) + item.count
end
end
local fluid_contents = arboretum.get_fluid_contents() or {}
--game.print("Inventory contents (map): " .. serpent.line(inv_contents))
--game.print("Fluid contents: " .. serpent.line(fluid_contents))
return need and
check(need.items, inv_contents) and
check(need.fluids, fluid_contents) and
{ ingredients = need, name = recipe.name } or nil
end
local function consume_ingredients(arboretum, need)
local inventory = arboretum.get_inventory(defines.inventory.assembling_machine_input)
for item, i in pairs(need.items or {}) do
inventory.remove({ name = item, count = i })
BioInd.writeDebug("Removed %s (%s)", { item, i })
end
BioInd.show("Inventory", inventory.get_contents() or "nil")
for fluid, f in pairs(need.fluids or {}) do
arboretum.remove_fluid({ name = fluid, amount = f })
BioInd.writeDebug("Removed %s (%s)", { fluid, f })
end
BioInd.show("Fluid contents", arboretum.get_fluid_contents() or "nil")
end
local function set_tile(current, target, surface, position)
if current ~= target then
surface.set_tiles(
{ { name = target, position = position } },
true, -- correct_tiles
true, -- remove_colliding_entities
true, -- remove_colliding_decoratives
true -- raise_event
)
end
end
function Get_Arboretum_Recipe(ArboretumTable, event)
BioInd.writeDebug("Entered function Get_Arboretum_Recipe(%s, %s)", { ArboretumTable, event })
if not ArboretumTable then
BioInd.writeDebug("%s is not a valid ArboretumTable. Leaving immediately!")
return
end
local arboretum = ArboretumTable.base
local new_position, currentTilename
local pos, surface, Inventory, stack
-- 'AlienBiomes' is a bool value -- we don't want to read it again if it's false,
-- but only if it hasn't been set yet!
AB = storage.compatible.AlienBiomes
terrain_name_g1 = terrain_name_g1 or (AB and "vegetation-green-grass-1" or "grass-1")
terrain_name_g3 = terrain_name_g3 or (AB and "vegetation-green-grass-3" or "grass-3")
local check = check_ingredients(arboretum)
local ingredients, recipe_name
if check then
--game.print("There are ingredients")
ingredients, recipe_name = check.ingredients, check.name
else
--game.print("No ingredients")
end
if ingredients then
local create_seedling, new_plant
pos = BioInd.normalize_position(arboretum.position) or
BioInd.arg_err("nil", "position")
surface = arboretum.surface
-- Just plant a tree and hope the ground is fertile!
if recipe_name == "bi-arboretum-r1" then
BioInd.writeDebug(tostring(recipe_name) .. ": Just plant a tree")
--- 10 attempts to find a random spot to plant a tree and/or change terrain
for k = 1, 10 do
new_position = get_new_position(pos)
new_plant = {
name = "seedling",
position = new_position,
force = "neutral"
}
if surface.can_place_entity(new_plant) then
consume_ingredients(arboretum, ingredients)
create_seedling = surface.create_entity(new_plant)
seed_planted_arboretum(event, create_seedling)
--- After sucessfully planting a tree, break out of the loop.
break
else
BioInd.writeDebug("Can't plant here (attempt %s)", k)
end
end
-- Fertilize the ground with normal fertilizer. Ignore tiles listed in Terrain_Check_1!
elseif recipe_name == "bi-arboretum-r2" then
BioInd.writeDebug(tostring(recipe_name) .. ": Just change terrain to grass-3 (basic)")
for k = 1, 10 do --- 10 attempts to find a random spot to plant a tree and / or change terrain
new_position = get_new_position(pos)
currentTilename = surface.get_tile(new_position.x, new_position.y).name
-- We need to fertilize the ground!
if Bi_Industries.fertility[currentTilename] and not Terrain_Check_1[currentTilename] then
consume_ingredients(arboretum, ingredients)
BioInd.writeDebug("%s: Changing terrain from %s to %s (%s)",
{ k, currentTilename or "unknown tile",
terrain_name_g3, serpent.line(new_position) })
set_tile(currentTilename, terrain_name_g3, surface, new_position)
--- After sucessfully changing the terrain, break out of the loop.
break
else
BioInd.writeDebug("%s: Can't change terrain (%s)",
{ k, currentTilename or "unknown tile" })
end
end
-- Fertilize the ground with advanced fertilizer. Ignore tiles listed in Terrain_Check_2!
elseif recipe_name == "bi-arboretum-r3" then
BioInd.writeDebug(tostring(recipe_name) .. ": Just change terrain to grass-1 (advanced)")
for k = 1, 10 do --- 10 attempts to find a random spot to plant a tree and / or change terrain
new_position = get_new_position(pos)
currentTilename = surface.get_tile(new_position.x, new_position.y).name
if Bi_Industries.fertility[currentTilename] and currentTilename ~= terrain_name_g1 then
consume_ingredients(arboretum, ingredients)
BioInd.writeDebug("%s: Changing terrain from %s to %s (%s)",
{ k, currentTilename or "unknown tile",
terrain_name_g1, serpent.line(new_position) })
set_tile(currentTilename, terrain_name_g1, surface, new_position)
--- After sucessfully changing the terrain, break out of the loop.
break
else
BioInd.writeDebug("%s: Can't change terrain (%s)",
{ k, currentTilename or "unknown tile" })
end
end
-- Fertilize the ground with normal fertilizer. Ignore tiles listed in Terrain_Check_1!
-- Also plant a tree.
elseif recipe_name == "bi-arboretum-r4" then
BioInd.writeDebug(tostring(recipe_name) .. ": Plant Tree AND change the terrain to grass-3 (basic)")
for k = 1, 10 do --- 10 attempts to find a random spot to plant a tree and / or change terrain
new_position = get_new_position(pos)
currentTilename = surface.get_tile(new_position.x, new_position.y).name
new_plant = {
name = "seedling",
position = new_position,
force = "neutral"
}
-- Test to see if we can plant
if surface.can_place_entity(new_plant) and Bi_Industries.fertility[currentTilename] then
consume_ingredients(arboretum, ingredients)
-- Refund fertilizer -- no need to waste it on fertile ground!
if Terrain_Check_1[currentTilename] then
arboretum.insert({ name = "fertilizer", count = ingredients.items.fertilizer })
BioInd.writeDebug("Refunded fertilizer!")
end
set_tile(currentTilename, terrain_name_g3, surface, new_position)
create_seedling = surface.create_entity(new_plant)
seed_planted_arboretum(event, create_seedling)
--- After sucessfully planting a tree or changing the terrain, break out of the loop.
break
else
BioInd.writeDebug("%s: Can't change terrain and plant a tree (%s)",
{ k, currentTilename or "unknown tile" })
end
end
-- Fertilize the ground with advanced fertilizer. Ignore tiles listed in Terrain_Check_2!
-- Also plant a tree.
elseif recipe_name == "bi-arboretum-r5" then
BioInd.writeDebug(tostring(recipe_name) .. ": Plant Tree and change the terrain to grass-1 (advanced)")
for k = 1, 10 do --- 10 attempts to find a random spot to plant a tree and / or change terrain
new_position = get_new_position(pos)
currentTilename = surface.get_tile(new_position.x, new_position.y).name
new_plant = {
name = "seedling",
position = new_position,
force = "neutral"
}
if surface.can_place_entity(new_plant) and Bi_Industries.fertility[currentTilename] then
consume_ingredients(arboretum, ingredients)
-- Refund fertilizer -- no need to waste it on fertile ground!
if Terrain_Check_2[currentTilename] then
arboretum.insert({
name = "bi-adv-fertilizer", count = ingredients.items["bi-adv-fertilizer"]
})
BioInd.writeDebug("Refunded advanced fertilizer!")
end
set_tile(currentTilename, terrain_name_g1, surface, new_position)
create_seedling = surface.create_entity(new_plant)
seed_planted_arboretum(event, create_seedling)
--- After sucessfully planting a tree or changing the terrain, break out of the loop.
break
else
BioInd.writeDebug("%s: Can't change terrain and plant a tree (%s)",
{ k, currentTilename or "unknown tile" })
end
end
else
BioInd.writeDebug("Terraformer has no recipe!")
end
end
end

View file

@ -0,0 +1,652 @@
-- All tree Growing stuff
local Event = require('__kry_stdlib__/stdlib/event/event').set_protected_mode(true)
local terrains = require("libs/trees-and-terrains")
Bi_Industries = {}
Bi_Industries.fertility = {
["vegetation-green-grass-1"] = 100,
["grass-1"] = 100,
["grass-3"] = 85,
["grass-2"] = 70,
["grass-4"] = 60,
["red-desert-0"] = 50,
["dirt-3"] = 40,
["dirt-5"] = 37,
["dirt-6"] = 34,
["dirt-7"] = 31,
["dirt-4"] = 28,
["dry-dirt"] = 25,
["dirt-2"] = 22,
["dirt-1"] = 19,
["red-desert-2"] = 16,
["red-desert-3"] = 13,
["sand-3"] = 10,
["sand-2"] = 7,
["sand-1"] = 4,
["red-desert-1"] = 1,
["frozen-snow-0"] = 1,
["frozen-snow-1"] = 1,
["frozen-snow-2"] = 1,
["frozen-snow-3"] = 1,
["frozen-snow-4"] = 1,
["frozen-snow-5"] = 1,
["frozen-snow-6"] = 1,
["frozen-snow-7"] = 1,
["frozen-snow-8"] = 1,
["frozen-snow-9"] = 1,
["mineral-aubergine-dirt-1"] = 45,
["mineral-aubergine-dirt-2"] = 45,
["mineral-aubergine-dirt-3"] = 25,
["mineral-aubergine-dirt-4"] = 25,
["mineral-aubergine-dirt-5"] = 25,
["mineral-aubergine-dirt-6"] = 25,
["mineral-aubergine-dirt-7"] = 25,
["mineral-aubergine-dirt-8"] = 25,
["mineral-aubergine-dirt-9"] = 25,
["mineral-aubergine-sand-1"] = 15,
["mineral-aubergine-sand-2"] = 15,
["mineral-aubergine-sand-3"] = 10,
["mineral-beige-dirt-1"] = 45,
["mineral-beige-dirt-2"] = 45,
["mineral-beige-dirt-3"] = 25,
["mineral-beige-dirt-4"] = 25,
["mineral-beige-dirt-5"] = 25,
["mineral-beige-dirt-6"] = 25,
["mineral-beige-dirt-7"] = 25,
["mineral-beige-dirt-8"] = 25,
["mineral-beige-dirt-9"] = 25,
["mineral-beige-sand-1"] = 10,
["mineral-beige-sand-2"] = 10,
["mineral-beige-sand-3"] = 10,
["mineral-black-dirt-1"] = 45,
["mineral-black-dirt-2"] = 45,
["mineral-black-dirt-3"] = 25,
["mineral-black-dirt-4"] = 25,
["mineral-black-dirt-5"] = 25,
["mineral-black-dirt-6"] = 25,
["mineral-black-dirt-7"] = 25,
["mineral-black-dirt-8"] = 25,
["mineral-black-dirt-9"] = 25,
["mineral-black-sand-1"] = 10,
["mineral-black-sand-2"] = 10,
["mineral-black-sand-3"] = 10,
["mineral-brown-dirt-1"] = 25,
["mineral-brown-dirt-2"] = 25,
["mineral-brown-dirt-3"] = 25,
["mineral-brown-dirt-4"] = 25,
["mineral-brown-dirt-5"] = 25,
["mineral-brown-dirt-6"] = 25,
["mineral-brown-dirt-7"] = 25,
["mineral-brown-dirt-8"] = 25,
["mineral-brown-dirt-9"] = 25,
["mineral-brown-sand-1"] = 10,
["mineral-brown-sand-2"] = 10,
["mineral-brown-sand-3"] = 10,
["mineral-cream-dirt-1"] = 25,
["mineral-cream-dirt-2"] = 25,
["mineral-cream-dirt-3"] = 25,
["mineral-cream-dirt-4"] = 25,
["mineral-cream-dirt-5"] = 25,
["mineral-cream-dirt-6"] = 25,
["mineral-cream-dirt-7"] = 25,
["mineral-cream-dirt-8"] = 25,
["mineral-cream-dirt-9"] = 25,
["mineral-cream-sand-1"] = 10,
["mineral-cream-sand-2"] = 10,
["mineral-cream-sand-3"] = 10,
["mineral-dustyrose-dirt-1"] = 25,
["mineral-dustyrose-dirt-2"] = 25,
["mineral-dustyrose-dirt-3"] = 25,
["mineral-dustyrose-dirt-4"] = 25,
["mineral-dustyrose-dirt-5"] = 25,
["mineral-dustyrose-dirt-6"] = 25,
["mineral-dustyrose-dirt-7"] = 25,
["mineral-dustyrose-dirt-8"] = 25,
["mineral-dustyrose-dirt-9"] = 25,
["mineral-dustyrose-sand-1"] = 10,
["mineral-dustyrose-sand-2"] = 10,
["mineral-dustyrose-sand-3"] = 10,
["mineral-grey-dirt-1"] = 25,
["mineral-grey-dirt-2"] = 25,
["mineral-grey-dirt-3"] = 25,
["mineral-grey-dirt-4"] = 25,
["mineral-grey-dirt-5"] = 25,
["mineral-grey-dirt-6"] = 25,
["mineral-grey-dirt-7"] = 25,
["mineral-grey-dirt-8"] = 25,
["mineral-grey-dirt-9"] = 25,
["mineral-grey-sand-1"] = 10,
["mineral-grey-sand-2"] = 10,
["mineral-grey-sand-3"] = 10,
["mineral-purple-dirt-1"] = 25,
["mineral-purple-dirt-2"] = 25,
["mineral-purple-dirt-3"] = 25,
["mineral-purple-dirt-4"] = 25,
["mineral-purple-dirt-5"] = 25,
["mineral-purple-dirt-6"] = 25,
["mineral-purple-dirt-7"] = 25,
["mineral-purple-dirt-8"] = 25,
["mineral-purple-dirt-9"] = 25,
["mineral-purple-sand-1"] = 10,
["mineral-purple-sand-2"] = 10,
["mineral-purple-sand-3"] = 10,
["mineral-red-dirt-1"] = 25,
["mineral-red-dirt-2"] = 25,
["mineral-red-dirt-3"] = 25,
["mineral-red-dirt-4"] = 25,
["mineral-red-dirt-5"] = 25,
["mineral-red-dirt-6"] = 25,
["mineral-red-dirt-7"] = 25,
["mineral-red-dirt-8"] = 25,
["mineral-red-dirt-9"] = 25,
["mineral-red-sand-1"] = 10,
["mineral-red-sand-2"] = 10,
["mineral-red-sand-3"] = 10,
["mineral-tan-dirt-1"] = 25,
["mineral-tan-dirt-2"] = 25,
["mineral-tan-dirt-3"] = 25,
["mineral-tan-dirt-4"] = 25,
["mineral-tan-dirt-5"] = 25,
["mineral-tan-dirt-6"] = 25,
["mineral-tan-dirt-7"] = 25,
["mineral-tan-dirt-8"] = 25,
["mineral-tan-dirt-9"] = 25,
["mineral-tan-sand-1"] = 10,
["mineral-tan-sand-2"] = 10,
["mineral-tan-sand-3"] = 10,
["mineral-violet-dirt-1"] = 25,
["mineral-violet-dirt-2"] = 25,
["mineral-violet-dirt-3"] = 25,
["mineral-violet-dirt-4"] = 25,
["mineral-violet-dirt-5"] = 25,
["mineral-violet-dirt-6"] = 25,
["mineral-violet-dirt-7"] = 25,
["mineral-violet-dirt-8"] = 25,
["mineral-violet-dirt-9"] = 25,
["mineral-violet-sand-1"] = 10,
["mineral-violet-sand-2"] = 10,
["mineral-violet-sand-3"] = 10,
["mineral-white-dirt-1"] = 25,
["mineral-white-dirt-2"] = 25,
["mineral-white-dirt-3"] = 25,
["mineral-white-dirt-4"] = 25,
["mineral-white-dirt-5"] = 25,
["mineral-white-dirt-6"] = 25,
["mineral-white-dirt-7"] = 25,
["mineral-white-dirt-8"] = 25,
["mineral-white-dirt-9"] = 25,
["mineral-white-sand-1"] = 10,
["mineral-white-sand-2"] = 10,
["mineral-white-sand-3"] = 10,
["vegetation-blue-grass-1"] = 70,
["vegetation-blue-grass-2"] = 70,
["vegetation-green-grass-2"] = 75,
["vegetation-green-grass-3"] = 85,
["vegetation-green-grass-4"] = 70,
["vegetation-mauve-grass-1"] = 70,
["vegetation-mauve-grass-2"] = 70,
["vegetation-olive-grass-1"] = 70,
["vegetation-olive-grass-2"] = 70,
["vegetation-orange-grass-1"] = 70,
["vegetation-orange-grass-2"] = 70,
["vegetation-purple-grass-1"] = 70,
["vegetation-purple-grass-2"] = 70,
["vegetation-red-grass-1"] = 70,
["vegetation-red-grass-2"] = 70,
["vegetation-turquoise-grass-1"] = 70,
["vegetation-turquoise-grass-2"] = 70,
["vegetation-violet-grass-1"] = 70,
["vegetation-violet-grass-2"] = 70,
["vegetation-yellow-grass-1"] = 70,
["vegetation-yellow-grass-2"] = 70,
["volcanic-blue-heat-1"] = 1,
["volcanic-blue-heat-2"] = 1,
["volcanic-blue-heat-3"] = 1,
["volcanic-blue-heat-4"] = 1,
["volcanic-green-heat-1"] = 1,
["volcanic-green-heat-2"] = 1,
["volcanic-green-heat-3"] = 1,
["volcanic-green-heat-4"] = 1,
["volcanic-orange-heat-1"] = 1,
["volcanic-orange-heat-2"] = 1,
["volcanic-orange-heat-3"] = 1,
["volcanic-orange-heat-4"] = 1,
["volcanic-purple-heat-1"] = 1,
["volcanic-purple-heat-2"] = 1,
["volcanic-purple-heat-3"] = 1,
["volcanic-purple-heat-4"] = 1,
["landfill"] = 1,
}
-- If we get passed on a tile_name, we can skip getting the tile at position!
local function get_tile_fertility(surface, position, tile_name)
surface = BioInd.is_surface(surface) or BioInd.arg_err(surface or "nil", "surface")
position = BioInd.normalize_position(position) or BioInd.arg_err(position or "nil", "position")
tile_name = tile_name or surface.get_tile(position.x, position.y).name
local fertility = Bi_Industries.fertility[tile_name]
return fertility and { fertility = fertility, key = "fertilizer" } or
{ fertility = 1, key = "default" }
end
local function plant_tree(tabl, tree, create_entity)
BioInd.check_args(tabl, "table")
BioInd.check_args(tree, "table")
BioInd.check_args(tree.time, "number", "time")
-- tree.tree_name is only required if we really want to create a tree,
-- not if we just want to add a table entry!
if create_entity then
BioInd.check_args(tree.tree_name, "string", "tree_name")
end
if not (tree.position and BioInd.normalize_position(tree.position)) then
BioInd.arg_err(tree.position or "nil", "position")
elseif not (tree.surface and BioInd.is_surface(tree.surface)) then
BioInd.arg_err(tree.surface or "nil", "surface")
end
local grow_until_tick = tree.time
BioInd.show("grow_until_tick", grow_until_tick)
tabl[grow_until_tick] = tabl[grow_until_tick] or {}
-- Update table
table.insert(tabl[grow_until_tick], tree)
BioInd.writeDebug("Added tree to table!")
-- Plant the new tree
if create_entity then
tree.surface.create_entity({
name = tree.tree_name,
position = tree.position,
force = "neutral"
})
end
end
-- t_base, t_penalty: numbers; seedbomb: Boolean
local function plant_seed(event, t_base, t_penalty, seedbomb)
for a, arg in pairs({
{ arg = event, type = "table" },
{ arg = t_base, type = "number" },
{ arg = t_penalty, type = "number" }
}) do
BioInd.check_args(arg.arg, arg.type, arg.desc)
end
BioInd.show("event", event)
BioInd.show("t_base", t_base)
BioInd.show("t_penalty", t_penalty)
BioInd.show("seedbomb", seedbomb)
-- Seed Planted (Put the seedling in the table)
local entity = event.entity or event.created_entity or
BioInd.arg_err("nil", "entity")
local surface = BioInd.is_surface(entity.surface) or
BioInd.arg_err(entity.surface or "nil", "surface")
local pos = BioInd.normalize_position(entity.position) or
BioInd.arg_err(entity.position or "nil", "position")
-- Minimum will always be 1
local fertility = get_tile_fertility(surface, pos).fertility
-- Things will grow faster on fertile than on barren tiles
-- (No penalty for tiles with maximum fertility)
local grow_time = math.max(1, math.random(t_base) + t_penalty - (40 * fertility))
local tree_data = {
position = pos,
time = event.tick + grow_time,
surface = surface,
seed_bomb = seedbomb
}
plant_tree(storage.bi.tree_growing, tree_data, false)
end
function seed_planted(event)
plant_seed(event, 1000, 4000, false)
end
function seed_planted_trigger(event)
plant_seed(event, 2000, 6000, true)
end
function seed_planted_arboretum(event, entity)
event.created_entity = entity
plant_seed(event, 2000, 6000, false)
end
function summ_weight(tabl)
local summ = 0
for i, tree_weights in pairs(tabl or {}) do
if (type(tree_weights) == "table") and tree_weights.weight then
summ = summ + tree_weights.weight
end
end
return summ
end
function tree_from_max_index_tabl(max_index, tabl)
BioInd.check_args(max_index, "number")
local rnd_index = math.random(max_index)
for tree_name, tree_weights in pairs(tabl or {}) do
if (type(tree_weights) == "table") and tree_weights.weight then
rnd_index = rnd_index - tree_weights.weight
if rnd_index <= 0 then
return tree_name
end
end
end
return nil
end
local function random_tree(tile_name)
BioInd.show("[random_tree] tile_name", tile_name)
if terrains[tile_name] then
local trees_table = terrains[tile_name]
local max_index = summ_weight(trees_table)
BioInd.writeDebug("Found %s in table terrains.\tmax_index: %s",
{ tile_name, max_index })
return tree_from_max_index_tabl(max_index, trees_table)
end
end
-- Settings used for the different grow stages
local stage_settings = {
[1] = {
fertilizer = { max = 1500, penalty = 3000, factor = 30 },
default = { max = 1500, penalty = 6000, factor = 30 },
},
[2] = {
fertilizer = { max = 1000, penalty = 2000, factor = 20 },
default = { max = 1500, penalty = 6000, factor = 30 },
},
[3] = {
fertilizer = { max = 1000, penalty = 2000, factor = 20 },
default = { max = 1500, penalty = 6000, factor = 30 },
},
}
local function Grow_tree_first_stage(first_stage_table, event)
BioInd.check_args(first_stage_table, "table")
BioInd.check_args(event, "table")
local surface = BioInd.is_surface(first_stage_table.surface) or
BioInd.arg_err(first_stage_table.surface or "nil", "surface")
local position = BioInd.normalize_position(first_stage_table.position) or
BioInd.arg_err(first_stage_table.position or "nil", "position")
local seed_bomb = first_stage_table.seed_bomb
local tree = surface.find_entity("seedling", position)
local tree2 = surface.find_entity("seedling-2", position)
local tree3 = surface.find_entity("seedling-3", position)
BioInd.writeDebug("tree: %s\ttree2: %s\ttree3: %s",
{ tree and tree.valid and tree.name or "nil",
tree2 and tree2.valid and tree2.name or "nil",
tree3 and tree3.valid and tree3.name or "nil" })
local tile_name = surface.get_tile(position).name
-- fertility will be 1 if terrain type is not listed above, so very small chance to grow.
local f = get_tile_fertility(surface, position, tile_name)
local fertility, key = f.fertility, f.key
BioInd.show("fertility", fertility)
BioInd.show("key", key)
-- Random value. Tree will grow if this value is smaller than the 'Fertility' value
local growth_chance = math.random(100)
local tree_name, can_be_placed
if tree or tree2 or tree3 then
BioInd.writeDebug("Found a seedling!")
tree_name = random_tree(tile_name)
end
BioInd.show("tree_name", tree_name)
if tree then
BioInd.writeDebug("Have tree")
if tree.valid then
tree.destroy()
BioInd.writeDebug("Destroyed tree!")
end
if tree_name and key == "fertilizer" and not seed_bomb then
-- Depending on Terrain, choose tree type & Convert seedling into a tree
BioInd.writeDebug("Fertilizer and no seed bomb: New tree can grow!")
-- Grow the new tree
can_be_placed = surface.can_place_entity({
name = tree_name, position = position, force = "neutral"
})
BioInd.show("can_be_placed", can_be_placed)
BioInd.show("growth_chance", growth_chance)
BioInd.show("fertility", fertility)
BioInd.show(growth_chance .. " <= (" .. fertility .. " + 5)", growth_chance <= (fertility + 5))
if can_be_placed and growth_chance <= (fertility + 5) then
BioInd.writeDebug("Can be placed etc!")
-- Trees will grow faster on Fertile than on barren tiles
local grow_time = math.max(1, math.random(2000) + 4000 - (40 * fertility))
BioInd.show("grow_time", grow_time)
local stage_1_tree_name = "bio-tree-" .. tree_name .. "-1"
if not (prototypes.item[stage_1_tree_name] or
prototypes.entity[stage_1_tree_name]) then
stage_1_tree_name = tree_name
end
BioInd.writeDebug("stage_1_tree_name: %s", { stage_1_tree_name })
local tree_data = {
tree_name = stage_1_tree_name,
final_tree = tree_name,
position = position,
time = event.tick + grow_time,
surface = surface
}
plant_tree(storage.bi.tree_growing_stage_1, tree_data, true)
end
end
end
--- Seed Bomb Code
BioInd.show("tree_name", tree_name)
BioInd.show("tree2", tree2)
BioInd.show("tree3", tree3)
if seed_bomb then
BioInd.writeDebug("Seed bomb was used!")
if tree2 and tree2.valid then
tree2.destroy()
BioInd.writeDebug("Removed tree2!")
end
if tree3 and tree3.valid then
tree3.destroy()
BioInd.writeDebug("Removed tree3!")
end
--- Depending on Terrain, choose tree type & Convert seedling into a tree
BioInd.show("key", key)
if key == "fertilizer" then
BioInd.writeDebug("Got Tile")
if tree_name then
BioInd.writeDebug("Found Tree: %s", { tree_name })
local new_tree = { name = tree_name, position = position, force = "neutral" }
can_be_placed = surface.can_place_entity(new_tree)
BioInd.show("can_be_placed", can_be_placed)
BioInd.show("growth_chance", growth_chance)
BioInd.show("fertility", fertility)
BioInd.show("growth_chance <= fertility", growth_chance <= fertility)
if can_be_placed and growth_chance <= fertility then
surface.create_entity(new_tree)
BioInd.writeDebug("Created new tree!")
end
else
BioInd.writeDebug("Tree not Found")
end
else
BioInd.writeDebug("Tile not Found")
end
end
end
local function Grow_tree_last_stage(last_stage_table)
BioInd.check_args(last_stage_table, "table")
BioInd.check_args(last_stage_table.tree_name, "string", "tree_name")
BioInd.check_args(last_stage_table.final_tree, "string", "final_tree")
local surface = BioInd.is_surface(last_stage_table.surface) or
BioInd.arg_err(last_stage_table.surface or "nil", "surface")
local position = BioInd.normalize_position(last_stage_table.position) or
BioInd.arg_err(last_stage_table.position or "nil", "position")
local tree_name = last_stage_table.tree_name
local final_tree = last_stage_table.final_tree
local tree = tree_name and surface.find_entity(tree_name, position)
if tree then
tree.destroy()
-- fertility will be 1 if terrain type not listed above, so very small change to grow.
local f = get_tile_fertility(surface, position)
local fertility, key = f.fertility, f.key
-- Random value. Tree will grow if this value is smaller than the 'Fertility' value
local growth_chance = math.random(100)
--- Convert growing tree to fully grown tree
if (key == "fertilizer" or growth_chance <= fertility) then
-- Grow the new tree
BioInd.writeDebug("Final Tree Name: %s", { final_tree })
surface.create_entity({
name = final_tree,
position = position,
force = "neutral"
})
end
end
end
local function Grow_tree_stage(stage_table, stage)
BioInd.writeDebug("Entered function Grow_tree_stage(%s, %s)", { stage_table, stage })
BioInd.check_args(stage_table, "table")
BioInd.check_args(stage, "number")
if stage == 4 then
Grow_tree_last_stage(stage_table)
else
for a, arg in pairs({
{ arg = stage_table.tree_name, type = "string", desc = "tree_name" },
{ arg = stage_table.final_tree, type = "string", desc = "final_tree" },
{ arg = stage_table.time, type = "number", desc = "time" },
}) do
BioInd.check_args(arg.arg, arg.type, arg.desc)
end
local tree_name = stage_table.tree_name
local final_tree = stage_table.final_tree
local time_planted = stage_table.time
local surface = BioInd.is_surface(stage_table.surface) or
BioInd.arg_err(stage_table.surface or "nil", "surface")
local position = BioInd.normalize_position(stage_table.position) or
BioInd.arg_err(stage_table.position or "nil", "position")
local tree = tree_name and surface.find_entity(tree_name, position)
if tree then
tree.destroy()
local next_stage = stage + 1
--- Depending on Terrain, choose tree type & Convert seedling into a tree
local f = get_tile_fertility(surface, position)
local fertility, key = f.fertility, f.key
local next_stage_tree_name = "bio-tree-" .. final_tree .. "-" .. next_stage
if not (prototypes.item[next_stage_tree_name] or
prototypes.entity[next_stage_tree_name]) then
next_stage_tree_name = final_tree
BioInd.writeDebug("Next stage %g: Prototype did not exist", { next_stage })
else
BioInd.writeDebug("Next stage %g: %s", { next_stage, next_stage_tree_name })
end
local can_be_placed = surface.can_place_entity {
name = next_stage_tree_name,
position = position,
force = "neutral"
}
if can_be_placed then
if next_stage_tree_name == final_tree then
BioInd.writeDebug("Tree reached final stage, don't insert")
surface.create_entity({
name = final_tree,
position = position,
force = "neutral"
})
else
-- Trees will grow faster on fertile than on barren tiles!
local s = stage_settings[stage][key]
local grow_time = math.max(1, math.random(s.max) + s.penalty - (s.factor * fertility))
local tree_data = {
tree_name = next_stage_tree_name,
final_tree = final_tree,
position = position,
time = time_planted + grow_time,
surface = surface
}
plant_tree(storage.bi["tree_growing_stage_" .. next_stage], tree_data, true)
end
end
else
BioInd.writeDebug("Did not find that tree I was looking for...")
end
end
end
---- Growing Tree
--Event.register(-12, function(event)
Event.register(defines.events.on_tick, function(event)
if storage.bi.tree_growing_stage_1 == nil then
for i = 1, 4 do
storage.bi["tree_growing_stage_" .. i] = storage.bi["tree_growing_stage_" .. i] or {}
end
end
local tick = event.tick
if storage.bi.tree_growing[tick] then
for t, tree_data in pairs(storage.bi.tree_growing[tick]) do
BioInd.writeDebug("Trying to move tree %s to first grow stage!", { t })
Grow_tree_first_stage(tree_data, event)
end
BioInd.writeDebug("Removing storage.bi.tree_growing[%s]!", { tick })
storage.bi.tree_growing[tick] = nil
end
local stage_table
for stage = 1, 4 do
stage_table = storage.bi["tree_growing_stage_" .. stage]
if stage_table[tick] then
for t, tree_data in pairs(stage_table[tick]) do
BioInd.writeDebug("Moving tree %s to next grow stage!", { t })
Grow_tree_stage(tree_data, stage)
end
BioInd.writeDebug("Removing storage.bi.tree_growing_stage_%s[%s]!",
{ stage, tick })
stage_table[tick] = nil
end
end
end)

View file

@ -0,0 +1,454 @@
local BioInd = require('common')('Bio_Industries_2')
local ICONPATH = "__Bio_Industries_2__/graphics/icons/"
-- If OwnlyMe's or Tral'a "Robot Tree Farm" mods are active, they will create variatons
-- of our variations of tree prototypes. Remove them!
local ignore_trees = BioInd.get_tree_ignore_list()
local removed = 0
for name, _ in pairs(ignore_trees or {}) do
if name:match("rtf%-bio%-tree%-.+%-%d-%d+") then
data.raw.tree[name] = nil
ignore_trees[name] = nil
removed = removed + 1
BioInd.show("Removed tree prototype", name)
end
end
BioInd.writeDebug("Removed %g tree prototypes. Number of trees to ignore now: %g", { removed, table_size(ignore_trees) })
BI.Settings.BI_Game_Tweaks_Emissions_Multiplier = settings.startup["BI_Game_Tweaks_Emissions_Multiplier"].value
---- Game Tweaks ---- Tree
if BI.Settings.BI_Game_Tweaks_Tree then
local new_results = {
{
type = "item",
name = "wood",
amount_min = 1,
amount_max = 6
}
}
for tree_name, tree in pairs(data.raw["tree"] or {}) do
if tree.minable and not ignore_trees[tree_name] then
BioInd.writeDebug("Tree name: %s\tminable.result: %s\tminable.count: %s",
{ tree.name, (tree.minable and tree.minable.result or "nil"), (tree.minable and tree.minable.count or "nil") },
"line")
BioInd.writeDebug("Tree name: %s\tminable.results: %s",
{ tree.name, (tree.minable and tree.minable.results or "nil") }, "line")
--CHECK FOR SINGLE RESULTS
-- mining.result may be set although mining.results exists (mining.result
-- will be ignored in that case; happens, for example with IR2's rubber
-- trees). In this case, overwriting mining.results with the data from
-- mining.result could break other mods (e.g. IR2's rubber trees should
-- yield "rubber-wood" instead of "wood").
if tree.minable.result and not tree.minable.results then
BioInd.writeDebug("Tree has minable.result")
--CHECK FOR VANILLA TREES WOOD x 4
if tree.minable.result == "wood" and tree.minable.count == 4 then
BioInd.writeDebug("Changing wood yield of %s to random value.", { tree.name })
tree.minable.mining_particle = "wooden-particle"
tree.minable.mining_time = 1.5
tree.minable.results = new_results
-- CONVERT RESULT TO RESULTS
else
BioInd.writeDebug("Converting tree.minable.result to tree.minable.results!")
tree.minable.mining_particle = "wooden-particle"
tree.minable.results = {
{
type = "item",
name = tree.minable.result,
amount = tree.minable.count,
}
}
end
--CHECK FOR RESULTS TABLE
elseif tree.minable.results then
BioInd.writeDebug("Checking minable.results!")
for r, result in pairs(tree.minable.results) do
--CHECK FOR RESULT WOOD x 4
if result.name == "wood" and result.amount == 4 then
BioInd.writeDebug("Changing result %s: %s", { r, result }, "line")
result.amount = nil
result.amount_min = 1
result.amount_max = 6
end
end
tree.minable.result = nil
tree.minable.count = nil
-- NEITHER RESULT NOR RESULTS EXIST -- CREATE RESULTS!
else
BioInd.writeDebug("Creating minable.results!")
tree.minable.results = new_results
end
BioInd.writeDebug("New minable.results: %s",
{ tree.minable and tree.minable.results or "nil" }, "line")
else
BioInd.writeDebug("Won't change results of %s!", { tree.name })
end
end
end
---- Game Tweaks ---- Player (Changed for 0.18.34/1.1.4!)
if BI.Settings.BI_Game_Tweaks_Player then
-- There may be more than one character in the game! Here's a list of
-- the character prototype names or patterns matching character prototype
-- names we want to ignore.
local blacklist = {
------------------------------------------------------------------------------------
-- Known dummies --
------------------------------------------------------------------------------------
-- Autodrive
"autodrive-passenger",
-- AAI Programmable Vehicles
"^.+%-_%-driver$",
-- Minime
"minime_character_dummy",
-- Water Turret (currently the dummies are not characters -- but things may change!)
"^WT%-.+%-dummy$",
------------------------------------------------------------------------------------
-- Other characters --
------------------------------------------------------------------------------------
-- Bob's Classes and Multiple characters mod
"^.*bob%-character%-.+$",
}
local whitelist = {
-- Default character
"^character$",
-- Characters compatible with Minime
"^.*skin.*$",
}
local tweaks = {
loot_pickup_distance = 5, -- default 2
build_distance = 20, -- Vanilla 6
drop_item_distance = 20, -- Vanilla 6
reach_distance = 20, -- Vanilla 6
item_pickup_distance = 6, -- Vanilla 1
reach_resource_distance = 6, -- Vanilla 2.7
}
local found, ignore
for char_name, character in pairs(data.raw.character) do
BioInd.show("Checking character", char_name)
found = false
for w, w_pattern in ipairs(whitelist) do
if char_name == w_pattern or char_name:match(w_pattern) then
ignore = false
BioInd.show("Found whitelisted character name", char_name)
for b, b_pattern in ipairs(blacklist) do
if char_name == b_pattern or char_name:match(b_pattern) then
BioInd.writeDebug("%s is on the ignore list!", char_name)
-- Mark character as found
ignore = true
break
end
end
if not ignore then
found = true
break
end
end
if found then
break
end
end
-- Apply tweaks
if found then
for tweak_name, tweak in pairs(tweaks) do
if character[tweak_name] < tweak then
BioInd.writeDebug("Changing %s from %s to %s", { tweak_name, character[tweak_name], tweak })
character[tweak_name] = tweak
end
end
end
end
end
---- Game Tweaks ---- Production science pack recipe
if data.raw.recipe["bi-production-science-pack"] then
BI_Functions.lib.allow_productivity("bi-production-science-pack")
thxbob.lib.tech.add_recipe_unlock("production-science-pack", "bi-production-science-pack")
BioInd.writeDebug("Unlock for recipe \"bi-production-science-pack\" added.")
end
---- Game Tweaks ---- Bots
if BI.Settings.BI_Game_Tweaks_Bot then
-- Logistic & Construction bots can't catch fire or be mined
local function immunify(bot)
local can_insert = true
bot.flags = bot.flags or {}
bot.resistances = bot.resistances or {}
for f, flag in pairs(bot.flags) do
if flag == "not-flammable" then
can_insert = false
break
end
end
if can_insert then
table.insert(bot.flags, "not-flammable")
BioInd.writeDebug("Added flag \"not-flammable\" to %s", { bot.name })
end
can_insert = true
for r, resistance in pairs(bot.resistances) do
if resistance.type == "fire" and resistance.percent ~= 100 then
BioInd.writeDebug("Change resistance against \"fire\" from %s to 100 %% for %s",
{ resistance.percent or "nil", bot.name })
bot.resistances[r] = { type = "fire", percent = 100 }
can_insert = false
break
end
end
if can_insert then
table.insert(bot.resistances, { type = "fire", percent = 100 })
BioInd.writeDebug("Added resistance against \"fire\" to %s", { bot.name })
end
bot.minable = nil
BioInd.writeDebug("Made %s unminable", { bot.name })
end
--catches modded bots too
for _, bot in pairs(data.raw['construction-robot']) do
immunify(bot)
end
for _, bot in pairs(data.raw['logistic-robot']) do
immunify(bot)
end
end
---- Game Tweaks stack size ----
if BI.Settings.BI_Game_Tweaks_Stack_Size then
-- Changed for 0.18.34/1.1.4
local tweaks = {
["wood"] = { value = 400, se_limit = 200 },
["stone"] = { value = 400, se_limit = 50 },
["stone-crushed"] = { value = 800, se_limit = 200 },
["concrete"] = { value = 400, se_limit = 200 },
["slag"] = { value = 800, se_limit = 200 },
}
local item
local five_dim = BioInd.get_startup_setting("5d-change-stack")
for tweak_name, tweak in pairs(tweaks) do
item = data.raw.item[tweak_name]
if item then
-- Only adjust stack_size if 5Dim sets multiplier of 1 or is not active!
if item.stack_size < tweak.value and (five_dim == 1 or not five_dim) then
BioInd.writeDebug("Changing stacksize of %s from %s to %s",
{ item.name, item.stack_size, tweak.value })
item.stack_size = tweak.value
end
if mods["space-exploration"] then
item.stack_size = math.min(tweak.se_limit, item.stack_size)
BioInd.show("Adjusted stack_size on account of SE", item.stack_size)
end
end
end
end
--- Update fuel_emissions_multiplier values
if BI.Settings.BI_Game_Tweaks_Emissions_Multiplier then
for item, factor in pairs({
["pellet-coke"] = 0.80,
["enriched-fuel"] = 0.90,
["solid-fuel"] = 1.00,
["solid-carbon"] = 1.05,
["carbon"] = 1.05,
["wood-bricks"] = 1.20,
["rocket-fuel"] = 1.20,
["bi-seed"] = 1.30,
["seedling"] = 1.30,
["bi-wooden-pole-big"] = 1.30,
["bi-wooden-pole-huge"] = 1.30,
["bi-wooden-fence"] = 1.30,
["bi-wood-pipe"] = 1.30,
["bi-wood-pipe-to-ground"] = 1.30,
["bi-wooden-chest-large"] = 1.30,
["bi-wooden-chest-huge"] = 1.30,
["bi-wooden-chest-giga"] = 1.30,
["bi-ash"] = 1.30,
["ash"] = 1.30,
["wood-charcoal"] = 1.25,
["cellulose-fiber"] = 1.40,
["bi-woodpulp"] = 1.40,
["solid-coke"] = 1.40,
["wood-pellets"] = 1.40,
["coal-crushed"] = 1.50,
["wood"] = 1.60,
["coal"] = 2.00,
}) do
BI_Functions.lib.fuel_emissions_multiplier_update(item, factor)
end
end
-- Make vanilla and Bio boilers exchangeable
if BI.Settings.BI_Bio_Fuel then
local boiler = data.raw["boiler"]["boiler"]
local boiler_group = boiler.fast_replaceable_group or "boiler"
boiler.fast_replaceable_group = boiler_group
data.raw["boiler"]["bi-bio-boiler"].fast_replaceable_group = boiler_group
end
if mods["Krastorio2"] or mods["Krastorio2-spaced-out"] then
-- Krastorio² needs much more wood than usually provided by Bio Industries. If Krastorio² is
-- active, BI should produce much more wood/wood pulp. For better baĺancing, our recipes should
-- also be changed to require more wood/wood pulp as ingredients.
-- Recipes for making wood should also use/produce more seeds, seedlings, and water. It shouldn't
-- be necessary to increase the input of ash and fertilizer in these recipes as they already
-- require more wood/wood pulp.
local update = {
"wood", "bi-woodpulp",
"bi-seed", "seedling", "water",
}
local multiply = function(items)
for _, item in pairs(items) do
for _, updateItem in pairs(update) do
if item.name == updateItem then
item.amount = item.amount * 4
end
end
end
end
for _, recipe in pairs(data.raw.recipe) do
BioInd.writeDebug("Recipe has \"mod\" property: %s", { recipe.mod and true or false })
if recipe.mod == "Bio_Industries_2" then
multiply(recipe.ingredients)
multiply(recipe.results)
BioInd.writeDebug("Changed ingredients for %s: %s",
{ recipe and recipe.name or "nil", recipe and recipe.ingredients or "nil" })
BioInd.writeDebug("Changed results for %s: %s",
{ recipe and recipe.name or "nil", recipe and recipe.results or "nil" })
end
end
end
-- Make sure fertilizers have the "place_as_tile" property!
local AlienBiomes = data.raw.tile["vegetation-green-grass-3"] and
data.raw.tile["vegetation-green-grass-1"] and true or false
-- We've already set place_as_tile. If it doesn't exist, our fertilizer definition has
-- been overwritten by some other mod, so we restore icons and localization and add
-- place_as_tile again!
local fertilizer = data.raw.item["fertilizer"]
if not fertilizer.place_as_tile then
fertilizer.place_as_tile = {
result = AlienBiomes and "vegetation-green-grass-3" or "grass-3",
condition_size = 1,
condition = { layers = { water_tile = true } }
}
fertilizer.icon = ICONPATH .. "fertilizer_64.png"
fertilizer.icon_size = 64
fertilizer.icons = {
{
icon = ICONPATH .. "fertilizer_64.png",
icon_size = 64,
}
}
fertilizer.localised_name = { "BI-item-name.fertilizer" }
fertilizer.localised_description = { "BI-item-description.fertilizer" }
end
data.raw.item["bi-adv-fertilizer"].place_as_tile = {
result = AlienBiomes and "vegetation-green-grass-1" or "grass-1",
condition_size = 1,
condition = { layers = { water_tile = true } }
}
if mods["pycoalprocessing"] and BI.Settings.BI_Bio_Fuel then
-- Bio_Fuel/recipe.lua:30: {type = "item", name = "bi-ash", amount = 15}
thxbob.lib.recipe.remove_result("bi-basic-gas-processing", "bi-ash")
thxbob.lib.recipe.add_result("bi-basic-gas-processing", {
type = "item",
name = "ash",
amount = 15
})
end
--- If Space Exploration Mod is installed.
if mods["space-exploration"] then
-- Space Exploration Mod likes Stack Sizes to be 200 max.
-- Changed in 1.1.11
local tweaks = {
["bi-solar-mat"] = 400,
["bi-seed"] = 800,
["seedling"] = 400,
["bi-woodpulp"] = 800,
["bi-ash"] = 400,
["wood-charcoal"] = 400,
["pellet-coke"] = 400,
["stone-crushed"] = 400,
}
local item
for tweak_name, tweak in pairs(tweaks) do
item = data.raw.item[tweak_name]
if item and item.stack_size then
item.stack_size = 200
end
end
if not mods["Natural_Evolution_Buildings"] then
local ammo_tweaks = {
["bi-dart-magazine-basic"] = 400,
["bi-dart-magazine-standard"] = 400,
["bi-dart-magazine-enhanced"] = 400,
["bi-dart-magazine-poison"] = 400,
}
local item
for tweak_name, tweak in pairs(ammo_tweaks) do
item = data.raw.ammo[tweak_name]
item.stack_size = 200
end
end
end
if BI.Settings.Bio_Cannon then
local default_target_masks = data.raw["utility-constants"].default.default_trigger_target_mask_by_type
default_target_masks["unit-spawner"] = default_target_masks["unit-spawner"] or
{ "common" } -- everything should have "common", unless there is specific reason not to
table.insert(default_target_masks["unit-spawner"], "Bio_Cannon_Ammo")
for w, worm in pairs(data.raw.turret) do
worm.trigger_target_mask = worm.trigger_target_mask or default_target_masks["turret"] or { "common" }
table.insert(worm.trigger_target_mask, "Bio_Cannon_Ammo")
end
end
------------------------------------------------------------------------------------
-- Add icons to our prototypes
BioInd.BI_add_icons()
---TESTING!
for k, v in pairs(data.raw) do
for t, p in pairs(v) do
if p.se_allow_in_space then
BioInd.writeDebug("%s (%s) can be built in space!", { p.name, t })
end
end
end

View file

@ -0,0 +1,713 @@
local BioInd = require('common')('Bio_Industries_2')
for var, name in pairs({
Bio_Cannon = "BI_Bio_Cannon",
BI_Bio_Fuel = "BI_Bio_Fuel",
BI_Easy_Bio_Gardens = "BI_Easy_Bio_Gardens",
BI_Game_Tweaks_Stack_Size = "BI_Game_Tweaks_Stack_Size",
BI_Game_Tweaks_Recipe = "BI_Game_Tweaks_Recipe",
BI_Game_Tweaks_Tree = "BI_Game_Tweaks_Tree",
BI_Game_Tweaks_Player = "BI_Game_Tweaks_Player",
BI_Game_Tweaks_Disassemble = "BI_Game_Tweaks_Disassemble",
BI_Game_Tweaks_Bot = "BI_Game_Tweaks_Bot",
BI_Solar_Additions = "BI_Solar_Additions",
}) do
BI.Settings[var] = BioInd.get_startup_setting(name)
end
BioInd.show("BI.Settings.BI_Easy_Bio_Gardens", BI.Settings.BI_Easy_Bio_Gardens)
local ICONPATH = "__Bio_Industries_2__/graphics/icons/"
local ICONPATH_E = BioInd.modRoot .. "/graphics/icons/entity/"
local ICONPATH_PY = "__Bio_Industries_2__/graphics/icons/mod_py/"
----Update the Wood Pipe Images
require("prototypes.Wood_Products.pipes")
-- Damage Bonus to Ammo
-- Don't duplicate what NE does
if not mods["Natural_Evolution_Buildings"] then
thxbob.lib.tech.add_recipe_unlock("military", "bi-dart-magazine-standard")
thxbob.lib.tech.add_recipe_unlock("military-2", "bi-dart-magazine-enhanced")
thxbob.lib.tech.add_recipe_unlock("military-3", "bi-dart-magazine-poison")
end
require("prototypes.Bio_Turret.technology-updates")
require("prototypes.Bio_Cannon.technology-updates")
if not mods["Natural_Evolution_Buildings"] and BI.Settings.Bio_Cannon then
-- add Prototype Artillery as pre req for artillery
thxbob.lib.tech.add_prerequisite("artillery", "bi-tech-bio-cannon")
end
--- Move Stone Crusher up in tech tree
thxbob.lib.tech.add_recipe_unlock("steel-processing", "bi-stone-crusher")
thxbob.lib.tech.add_recipe_unlock("steel-processing", "bi-crushed-stone-1")
-- Unlock recipes for Crushed Stone from concrete/hazard concrete
thxbob.lib.tech.add_recipe_unlock("advanced-material-processing-2", "bi-crushed-stone-2")
thxbob.lib.tech.add_recipe_unlock("advanced-material-processing-2", "bi-crushed-stone-3")
thxbob.lib.tech.add_recipe_unlock("advanced-material-processing-2", "bi-crushed-stone-4")
thxbob.lib.tech.add_recipe_unlock("advanced-material-processing-2", "bi-crushed-stone-5")
-- Add Wooden Chests
thxbob.lib.tech.add_recipe_unlock("logistics", "bi-wooden-chest-large")
thxbob.lib.tech.add_recipe_unlock("logistics-2", "bi-wooden-chest-huge")
thxbob.lib.tech.add_recipe_unlock("logistics-3", "bi-wooden-chest-giga")
-- Add Big and Huge electric poles to tech tree
thxbob.lib.tech.add_recipe_unlock("logistics", "bi-wooden-pole-big")
thxbob.lib.tech.add_recipe_unlock("electric-energy-distribution-2", "bi-wooden-pole-huge")
--- Wood Floors
-- Make wood placeable only if Dectorio isn't installed. Should leave existing flooring intact.
if not mods["Dectorio"] then
data.raw.item["wood"].place_as_tile = {
result = "bi-wood-floor",
condition_size = 4,
condition = { layers = { water_tile = true } }
}
end
--- Make it so that the Base game tile "grass" can't be placed in blueprints
--- New as of 0.16
for _, tile in ipairs { "grass-1", "grass-2", "grass-3", "grass-4" } do
BI_Functions.lib.remove_from_blueprint(tile)
end
if mods["alien-biomes"] then
BioInd.writeDebug("Removing AB tiles from blueprints")
local patterns = {
"frozen%-snow%-%d",
"mineral%-aubergine%-dirt%-%d",
"mineral%-aubergine%-sand%-%d",
"mineral%-beige%-dirt%-%d",
"mineral%-beige%-sand%-%d",
"mineral%-black%-dirt%-%d",
"mineral%-black%-sand%-%d",
"mineral%-brown%-dirt%-%d",
"mineral%-brown%-sand%-%d",
"mineral%-cream%-dirt%-%d",
"mineral%-cream%-sand%-%d",
"mineral%-dustyrose%-dirt%-%d",
"mineral%-dustyrose%-sand%-%d",
"mineral%-grey%-dirt%-%d",
"mineral%-grey%-sand%-%d",
"mineral%-purple%-dirt%-%d",
"mineral%-purple%-sand%-%d",
"mineral%-red%-dirt%-%d",
"mineral%-red%-sand%-%d",
"mineral%-tan%-dirt%-%d",
"mineral%-tan%-sand%-%d",
"mineral%-violet%-dirt%-%d",
"mineral%-violet%-sand%-%d",
"mineral%-white%-dirt%-%d",
"mineral%-white%-sand%-%d",
"vegetation%-blue%-grass%-%d",
"vegetation%-green%-grass%-%d",
"vegetation%-mauve%-grass%-%d",
"vegetation%-olive%-grass%-%d",
"vegetation%-orange%-grass%-%d",
"vegetation%-purple%-grass%-%d",
"vegetation%-red%-grass%-%d",
"vegetation%-turquoise%-grass%-%d",
"vegetation%-violet%-grass%-%d",
"vegetation%-yellow%-grass%-%d",
"volcanic%-blue%-heat%-%d",
"volcanic%-green%-heat%-%d",
"volcanic%-orange%-heat%-%d",
"volcanic%-purple%-heat%-%d",
}
for tile_name, tile in pairs(data.raw.tile) do
for p, pattern in ipairs(patterns) do
if tile_name:match(pattern) then
BI_Functions.lib.remove_from_blueprint(tile)
break
end
end
end
end
--- Adds Solar Farm, Solar Plant, Musk Floor, Bio Accumulator and Substation to Tech tree
if BI.Settings.BI_Solar_Additions then
if data.raw.technology["bob-solar-energy-2"] then
thxbob.lib.tech.add_recipe_unlock("bob-electric-energy-accumulators-3", "bi-bio-accumulator")
thxbob.lib.tech.add_recipe_unlock("electric-energy-distribution-2", "bi-large-substation")
thxbob.lib.tech.add_recipe_unlock("bob-solar-energy-2", "bi-bio-solar-farm")
thxbob.lib.tech.add_recipe_unlock("bob-solar-energy-2", "bi-solar-boiler-hidden-panel")
else
thxbob.lib.tech.add_recipe_unlock("electric-energy-accumulators", "bi-bio-accumulator")
thxbob.lib.tech.add_recipe_unlock("electric-energy-distribution-2", "bi-large-substation")
thxbob.lib.tech.add_recipe_unlock("solar-energy", "bi-bio-solar-farm")
thxbob.lib.tech.add_recipe_unlock("solar-energy", "bi-solar-boiler-hidden-panel")
end
if data.raw.technology["bob-solar-energy-3"] then
thxbob.lib.tech.add_recipe_unlock("bob-solar-energy-3", "bi-solar-mat")
else
thxbob.lib.tech.add_recipe_unlock("solar-energy", "bi-solar-mat")
end
--- Electric redo if Bob' Electric
-- Huge Electric Pole
if data.raw.item["tinned-copper-cable"] then
thxbob.lib.recipe.remove_ingredient("bi-wooden-pole-huge", "wood")
thxbob.lib.recipe.add_new_ingredient("bi-wooden-pole-huge", {
type = "item",
name = "tinned-copper-cable",
amount = 15
}
)
end
-- Solar Farm
if data.raw.item["solar-panel-large"] then
thxbob.lib.recipe.remove_ingredient("bi-bio-solar-farm", "solar-panel")
thxbob.lib.recipe.add_new_ingredient("bi-bio-solar-farm", {
type = "item",
name = "solar-panel-large",
amount = 30
}
)
end
-- Huge Sub Station
if data.raw.item["substation-3"] then
thxbob.lib.recipe.remove_ingredient("bi-large-substation", "substation")
thxbob.lib.recipe.add_new_ingredient("bi-large-substation", {
type = "item",
name = "substation-3",
amount = 6
}
)
end
if data.raw.item["electrum-alloy"] then
thxbob.lib.recipe.remove_ingredient("bi-large-substation", "steel-plate")
thxbob.lib.recipe.add_new_ingredient("bi-large-substation", {
type = "item",
name = "electrum-alloy",
amount = 10
}
)
end
-- Huge Accumulator
if data.raw.item["large-accumulator-2"] then
thxbob.lib.recipe.remove_ingredient("bi-bio-accumulator", "accumulator")
thxbob.lib.recipe.add_new_ingredient("bi-bio-accumulator", {
type = "item",
name = "large-accumulator",
amount = 30
}
)
end
if data.raw.item["aluminium-plate"] then
thxbob.lib.recipe.remove_ingredient("bi-bio-accumulator", "copper-cable")
thxbob.lib.recipe.add_new_ingredient("bi-bio-accumulator", {
type = "item",
name = "aluminium-plate",
amount = 50
}
)
end
-- Solar Mat
if data.raw.item["aluminium-plate"] then
thxbob.lib.recipe.remove_ingredient("bi-solar-mat", "steel-plate")
thxbob.lib.recipe.add_new_ingredient("bi-solar-mat", {
type = "item",
name = "aluminium-plate",
amount = 1
}
)
end
if data.raw.item["silicon-wafer"] then
thxbob.lib.recipe.remove_ingredient("bi-solar-mat", "copper-cable")
thxbob.lib.recipe.add_new_ingredient("bi-solar-mat", {
type = "item",
name = "silicon-wafer",
amount = 4
}
)
end
-- Solar Boiler / Plant
if data.raw.item["angels-electric-boiler"] then
thxbob.lib.recipe.remove_ingredient("bi-solar-boiler-hidden-panel", "boiler")
thxbob.lib.recipe.add_new_ingredient("bi-solar-boiler-hidden-panel", {
type = "item",
name = "angels-electric-boiler",
amount = 1
}
)
end
end
require("prototypes.Bio_Farm.compatible_recipes") -- Bob and Angels mesh
require("prototypes.Bio_Farm.technology2")
-- Replace fertilizer/advanced fertilizer + water with fluid fertilizers in Bio garden recipes!
BioInd.show("data-updates.lua -- BI.Settings.BI_Easy_Bio_Gardens", BI.Settings.BI_Easy_Bio_Gardens)
if BI.Settings.BI_Easy_Bio_Gardens then
BioInd.writeDebug("Must create fluid fertilizers!")
require("prototypes.Bio_Garden.fluid_fertilizer")
end
-- Blacklist bioreactor in Assembler Pipe Passthrough
if mods["assembler-pipe-passthrough"] then
appmod.blacklist['bi-bio-reactor'] = true
end
-- Adds Bio recipes
if BI.Settings.BI_Bio_Fuel then
thxbob.lib.tech.add_recipe_unlock("bi-tech-advanced-biotechnology", "bi-cellulose-1")
thxbob.lib.tech.add_recipe_unlock("bi-tech-advanced-biotechnology", "bi-cellulose-2")
-- Remove unlock for biomass-1 and add it again so all biomass recipes are next to each
-- other in the preview of technology unlocks!
thxbob.lib.tech.remove_recipe_unlock("bi-tech-advanced-biotechnology", "bi-biomass-1")
for u, unlock in ipairs({
"bi-biomass-1", "bi-biomass-2", "bi-biomass-3",
"bi-battery",
"bi-biomass-conversion-1", "bi-biomass-conversion-2", "bi-biomass-conversion-3", "bi-biomass-conversion-4",
"bi-acid", "bi-bio-boiler"
}) do
thxbob.lib.tech.add_recipe_unlock("bi-tech-advanced-biotechnology", unlock)
end
-- Added for 0.17.49/0.18.17 (changed for 0.18.29)
thxbob.lib.tech.add_recipe_unlock("bi-tech-coal-processing-2", "bi-basic-gas-processing")
if mods["angelspetrochem"] then
thxbob.lib.tech.add_recipe_unlock("bi-tech-advanced-biotechnology", "bi-sulfur-angels")
else
thxbob.lib.tech.add_recipe_unlock("bi-tech-advanced-biotechnology", "bi-sulfur")
end
else
thxbob.lib.recipe.add_new_ingredient("bi-adv-fertilizer-1", { type = "item", name = "fertilizer", amount = 50 })
thxbob.lib.recipe.remove_ingredient("bi-adv-fertilizer-2", "fertilizer")
thxbob.lib.recipe.add_new_ingredient("bi-adv-fertilizer-2", { type = "item", name = "fertilizer", amount = 30 })
end
--- if the Alien Artifact is in the game, use it for some recipes
if data.raw.item["alien-artifact"] then
--- Advanced fertilizer will use Alien Artifact
thxbob.lib.recipe.remove_ingredient("bi-adv-fertilizer-1", "bi-biomass")
thxbob.lib.recipe.add_new_ingredient("bi-adv-fertilizer-1", {
type = "item",
name = "alien-artifact",
amount = 5
}
)
thxbob.lib.tech.add_recipe_unlock("bi-tech-advanced-biotechnology", "bi-adv-fertilizer-1")
end
------- Adds a Mk3 recipe for wood if you're playing with Natural Evolution Buildings
if mods["Natural_Evolution_Buildings"] then
thxbob.lib.recipe.remove_ingredient("bi-adv-fertilizer-1", "bi-biomass")
thxbob.lib.recipe.remove_ingredient("bi-adv-fertilizer-1", "alien-artifact")
thxbob.lib.recipe.add_new_ingredient("bi-adv-fertilizer-1", {
type = "fluid",
name = "NE_enhanced-nutrient-solution",
amount = 50
}
)
end
------------ Support for Bob's Greenhouse
if data.raw["item"]["bob-greenhouse"] then
data.raw["item"]["seedling"].place_result = "seedling"
data.raw["item"]["seedling"].icon = ICONPATH .. "Seedling.png"
data.raw["item"]["seedling"].icon_size = 64
data.raw["item"]["fertilizer"].icon = ICONPATH .. "fertilizer.png"
data.raw["item"]["fertilizer"].icon_size = 64
data.raw["item"]["fertilizer"].place_as_tile = {
result = BioInd.AB_tiles() and "vegetation-green-grass-3" or "grass-3",
condition_size = 1,
condition = { layers = { water_tile = true } }
}
end
if settings.startup["angels-use-angels-barreling"] and settings.startup["angels-use-angels-barreling"].value then
data.raw.technology["bi-tech-fertilizer"].prerequisites = {
"bi-tech-bio-farming",
-- AND (
"water-treatment", -- sulfur
-- OR
"angels-fluid-barreling", -- barreling (needed 'water-treatment' as prerequisites)
-- )
}
end
----- Angels Merge ----
if mods["angelspetrochem"] then
data.raw.item["pellet-coke"].icon = "__angelspetrochem__/graphics/icons/pellet-coke.png"
data.raw.item["pellet-coke"].icon_size = 32
data.raw.item["pellet-coke"].fuel_acceleration_multiplier = 1.1
data.raw.item["pellet-coke"].fuel_top_speed_multiplier = 1.2
data.raw.recipe["pellet-coke"].category = "biofarm-mod-smelting"
thxbob.lib.tech.remove_recipe_unlock("angels-coal-processing-2", "pellet-coke")
thxbob.lib.tech.add_recipe_unlock("angels-coal-cracking", "pellet-coke")
end
if data.raw.item["ash"] and mods["pycoalprocessing"] then
thxbob.lib.recipe.replace_ingredient("bi-fertilizer-2", "bi-ash", "ash")
if mods["angelsrefining"] then
thxbob.lib.recipe.replace_ingredient("bi-slag-slurry", "bi-ash", "ash")
end
thxbob.lib.recipe.replace_ingredient("bi-seed-2", "bi-ash", "ash")
thxbob.lib.recipe.replace_ingredient("bi-seedling-2", "bi-ash", "ash")
thxbob.lib.recipe.replace_ingredient("bi-logs-2", "bi-ash", "ash")
data.raw.recipe["bi-ash-1"].result = "ash"
data.raw.recipe["bi-ash-2"].result = "ash"
thxbob.lib.recipe.replace_ingredient("bi-stone-brick", "bi-ash", "ash")
thxbob.lib.recipe.replace_ingredient("bi-fertilizer-1", "bi-ash", "ash")
if BI.Settings.BI_Bio_Fuel then
thxbob.lib.recipe.replace_ingredient("bi-biomass-3", "bi-ash", "ash")
thxbob.lib.recipe.replace_ingredient("bi-sulfur", "bi-ash", "ash")
thxbob.lib.recipe.replace_ingredient("bi-sulfur-angels", "bi-ash", "ash")
data.raw.recipe["bi-sulfur"].icon = ICONPATH_PY .. "py_bio_sulfur.png"
data.raw.recipe["bi-sulfur"].icon_size = 64
end
data.raw.item["bi-ash"] = nil
data.raw.recipe["bi-ash-1"].icon = "__pycoalprocessinggraphics__/graphics/icons/ash.png"
data.raw.recipe["bi-ash-1"].icon_size = 32
data.raw.recipe["bi-ash-2"].icon = "__pycoalprocessinggraphics__/graphics/icons/ash.png"
data.raw.recipe["bi-ash-2"].icon_size = 32
-- Use ash icon from pycoalprocessing in icons of recipes using ash
data.raw.recipe["bi-seed-2"].icon = ICONPATH_PY .. "py_bio_seed2.png"
data.raw.recipe["bi-seed-2"].icon_size = 64
data.raw.recipe["bi-seedling-2"].icon = ICONPATH_PY .. "py_Seedling2.png"
data.raw.recipe["bi-seedling-2"].icon_size = 64
data.raw.recipe["bi-logs-2"].icon = ICONPATH_PY .. "py_raw-wood-mk2.png"
data.raw.recipe["bi-logs-2"].icon_size = 64
data.raw.recipe["bi-ash-1"].icon = ICONPATH_PY .. "py_ash_raw-wood.png"
data.raw.recipe["bi-ash-1"].icon_size = 64
data.raw.recipe["bi-ash-2"].icon = ICONPATH_PY .. "py_ash_woodpulp.png"
data.raw.recipe["bi-ash-2"].icon_size = 64
data.raw.recipe["bi-stone-brick"].icon = ICONPATH_PY .. "py_bi_stone_brick.png"
data.raw.recipe["bi-stone-brick"].icon_size = 64
end
----- If Bob's bobrevamp, then ----
if mods["bobrevamp"] then
thxbob.lib.tech.remove_recipe_unlock("bi-tech-coal-processing-1", "bi-solid-fuel")
thxbob.lib.tech.add_recipe_unlock("solid-fuel", "bi-solid-fuel")
end
----- If Simple Silicon is active, add solar cell to Musk floor (solar mat) recipe
if mods["SimpleSilicon"] then
thxbob.lib.recipe.add_new_ingredient("bi-solar-mat", {
type = "item",
name = "SiSi-solar-cell",
amount = 1
})
end
-- We may need liquid air and nitrogen -- but not if any of the following mods is active!
local ICONPATH = BioInd.modRoot .. "/graphics/icons/"
-- We only want to create nitrogen if it doesn't exist yet. We then also need to create
-- liquid air.
if not data.raw.fluid["nitrogen"] then
data:extend({
{
type = "fluid",
name = "nitrogen",
icon = ICONPATH .. "nitrogen.png",
icon_size = 64,
icons = {
{
icon = ICONPATH .. "nitrogen.png",
icon_size = 64,
icon_mipmaps = 1,
}
},
default_temperature = 25,
gas_temperature = -210,
max_temperature = 100,
heat_capacity = "1kJ",
base_color = { r = 0.0, g = 0.0, b = 1.0 },
flow_color = { r = 0.0, g = 0.0, b = 1.0 },
pressure_to_speed_ratio = 0.4,
flow_to_energy_ratio = 0.59,
subgroup = "bio-bio-farm-intermediate-product",
order = "ab"
},
})
BioInd.writeDebug("Made recipe for \"nitrogen\".")
if not data.raw.fluid["liquid-air"] then
data:extend({
{
type = "fluid",
name = "liquid-air",
icon = ICONPATH .. "liquid-air.png",
icon_size = 64,
icons = {
{
icon = ICONPATH .. "liquid-air.png",
icon_size = 64,
icon_mipmaps = 1,
}
},
default_temperature = 25,
gas_temperature = -100,
max_temperature = 100,
heat_capacity = "1kJ",
base_color = { r = 0, g = 0, b = 0 },
flow_color = { r = 0.5, g = 1.0, b = 1.0 },
pressure_to_speed_ratio = 0.4,
flow_to_energy_ratio = 0.59,
subgroup = "bio-bio-farm-intermediate-product",
order = "aa"
},
})
BioInd.writeDebug("Made recipe for \"liquid-air\".")
end
-- Recipes for "bi-liquid-air" and "bi-nitrogen" aren't needed!
else
-- Remove recipe unlocks
thxbob.lib.tech.remove_recipe_unlock("bi-tech-fertilizer", "bi-liquid-air")
thxbob.lib.tech.remove_recipe_unlock("bi-tech-fertilizer", "bi-nitrogen")
BioInd.writeDebug("Removed recipe unlocks for \"bi-liquid-air\" and \"bi-nitrogen\"")
-- Replace liquid air with oxygen (from Krastorio/K2) in recipes for Algae Biomass 2 and 3
if data.raw.fluid.oxygen then
thxbob.lib.recipe.replace_ingredient("bi-biomass-2", "liquid-air", "oxygen")
thxbob.lib.recipe.replace_ingredient("bi-biomass-3", "liquid-air", "oxygen")
BioInd.writeDebug("Replaced \"liquid-air\" with \"oxygen\" in recipes \"bi-biomass-2\" and \"bi-biomass-3\"")
-- Perhaps there is no oxygen? But there's nitrogen for sure, so we fall back to that!
elseif data.raw.fluid.nitrogen then
thxbob.lib.recipe.replace_ingredient("bi-biomass-2", "liquid-air", "nitrogen")
thxbob.lib.recipe.replace_ingredient("bi-biomass-3", "liquid-air", "nitrogen")
BioInd.writeDebug("Replaced \"liquid-air\" with \"nitrogen\" in recipes \"bi-biomass-2\" and \"bi-biomass-3\"")
end
-- Remove recipes for these fluids
data.raw.recipe["bi-liquid-air"] = nil
data.raw.recipe["bi-nitrogen"] = nil
BioInd.writeDebug("Removed recipes for \"nitrogen\" and \"liquid air\".")
end
-- Moved here from data-final-fixes.lua for 0.18.34/1.1.4! (Fixes https://mods.factorio.com/mod/Bio_Industries/discussion/5ff570bd916993002371332a)
---- Game Tweaks ---- Recipes
if BI.Settings.BI_Game_Tweaks_Recipe then
--- Concrete Recipe Tweak
thxbob.lib.recipe.remove_ingredient("concrete", "iron-ore")
thxbob.lib.recipe.add_new_ingredient("concrete", { type = "item", name = "iron-stick", amount = 2 })
--- Stone Wall
thxbob.lib.recipe.add_new_ingredient("stone-wall", { type = "item", name = "iron-stick", amount = 1 })
--- Rail Stuff
--(Remove Stone and Add Crushed Stone)
if data.raw.item["stone-crushed"] then
thxbob.lib.recipe.remove_ingredient("rail", "stone")
thxbob.lib.recipe.add_new_ingredient("rail", { type = "item", name = "stone-crushed", amount = 6 })
thxbob.lib.recipe.remove_ingredient("bi-rail-wood", "stone")
thxbob.lib.recipe.add_new_ingredient("bi-rail-wood", { type = "item", name = "stone-crushed", amount = 6 })
end
-- vanilla rail recipe update
thxbob.lib.recipe.remove_ingredient("rail", "iron-stick")
thxbob.lib.recipe.add_new_ingredient("rail", { type = "item", name = "concrete", amount = 2 })
data.raw["legacy-straight-rail"]["legacy-straight-rail"].icon = ICONPATH_E .. "rail-concrete.png"
data.raw["straight-rail"]["straight-rail"].icon = ICONPATH_E .. "rail-concrete.png"
--- Wood Rail added to Tech
thxbob.lib.tech.add_recipe_unlock("railway", "bi-rail-wood")
thxbob.lib.tech.add_recipe_unlock("railway", "bi-rail-wood-to-concrete")
end
-- Moved here from data-final-fixes.lua for 0.18.34/1.1.4!
---- Game Tweaks ---- Disassemble Recipes
require("prototypes.Bio_Tweaks.recipe")
if BI.Settings.BI_Game_Tweaks_Disassemble then
for recipe, tech in pairs({
["bi-burner-mining-drill-disassemble"] = "automation-2",
["bi-burner-inserter-disassemble"] = "automation-2",
["bi-long-handed-inserter-disassemble"] = "automation-2",
["bi-stone-furnace-disassemble"] = "automation-2",
["bi-steel-furnace-disassemble"] = "advanced-material-processing",
}) do
thxbob.lib.tech.add_recipe_unlock(tech, recipe)
end
end
--- Enable Productivity in Recipes
for recipe, r in pairs(data.raw.recipe) do
for p, pattern in ipairs({
"bi%-acid",
"bi%-battery",
"bi%-biomass%-%d",
"bi%-biomass%-conversion%-%d",
"bi%-cellulose%-%d",
"bi%-crushed%-stone%-%d",
"bi%-liquid%-air",
"bi%-logs%-%d",
"bi%-nitrogen",
"bi%-plastic%-%d",
"bi%-press%-wood",
"bi%-resin%-pulp",
"bi%-resin%-wood",
"bi%-seed%-%d",
"bi%-seedling%-%d",
"bi%-stone%-brick",
"bi%-sulfur",
"bi%-sulfur%-angels",
"bi%-wood%-from%-pulp",
"bi%-woodpulp",
-- Added for 0.17.49/0.18.17
"bi%-basic%-gas%-processing",
}) do
if recipe:match(pattern) then
BI_Functions.lib.allow_productivity(recipe)
break
end
end
end
------------------------------------------------------------------------------------
-- Add resistances to our hidden entities
------------------------------------------------------------------------------------
-- Make resistances for each damage type
local resistances = {}
for damage, d in pairs(data.raw["damage-type"]) do
resistances[#resistances + 1] = {
type = damage,
percent = 100
}
end
-- Add resistances to prototypes
-- (h_type is not guaranteed to be a prototype type -- it's the short handle that we
-- use compound_entities.hidden!)
local h_type
for h_key, h_names in pairs(BI.hidden_entities.types) do
h_type = BioInd.HE_map[h_key]
for h_name, h in pairs(h_names) do
data.raw[h_type][h_name].resistances = resistances
BioInd.writeDebug("Added resistances to %s (%s): %s",
{ h_name, h_type, data.raw[h_type][h_name].resistances })
end
end
-- Adjust resistances for radar of the terraformers. Unlike the other hidden parts
-- of compound entities, this one is visible, and should suffer the same as the base
-- when it gets hurt. (Also, damaging the radar will damage the base entity as well.)
local compound = BioInd.compound_entities["bi-arboretum"]
local b = compound.base
local r = compound.hidden.radar
if b and r then
local resistances = data.raw[b.type][b.name].resistances
if resistances then
data.raw[r.type][r.name].resistances = util.table.deepcopy(resistances)
BioInd.writeDebug("Copied resistances from %s to %s!", { b.name, r.name })
end
end
------------------------------------------------------------------------------------
-- Omnifluid will be confused by our bi-solar-boiler (the compound boiler + solar
-- plant entity). Let's blacklist it if the mod is active!
BioInd.show("Omnifluid is active", mods["omnimatter_fluid"] or "false")
BioInd.show("forbidden_boilers", forbidden_boilers)
if mods["omnimatter_fluid"] then
forbidden_boilers = forbidden_boilers or {}
forbidden_boilers["bi-solar-boiler"] = true
end
BioInd.writeDebug("OMNIFLUID Test! forbidden_boilers = %s", { forbidden_boilers })
------------------------------------------------------------------------------------
-- If the Py-Suite is installed, we move our coal-processing unlocks to their techs!
local check, set
if mods["pyrawores"] then
-- Are all techs there?
check = true
for i = 1, 3 do
if not data.raw.technology["coal-mk0" .. i] then
check = false
break
end
end
if check then
set = true
local unlocks = require("prototypes.Bio_Farm.coal_processing")
for i = 1, 3 do
for u, unlock in ipairs(unlocks[i]) do
thxbob.lib.tech.add_recipe_unlock("coal-mk0" .. i, unlock.recipe)
BioInd.writeDebug("Added recipe %s to unlocks of %s", { unlock.recipe, "coal-mk0" .. i })
end
end
end
end
-- PyRawOres has priority!
if mods["pycoalprocessing"] and not set then
-- Are all techs there?
check = true
for i = 1, 3 do
if not data.raw.technology["coal-processing-" .. i] then
check = false
break
end
end
if check then
set = true
local unlocks = require("prototypes.Bio_Farm.coal_processing")
for i = 1, 3 do
for u, unlock in ipairs(unlocks[i]) do
thxbob.lib.tech.add_recipe_unlock("coal-processing-" .. i, unlock.recipe)
BioInd.writeDebug("Added recipe %s to unlocks of %s", { unlock.recipe, "coal-processing-" .. i })
end
end
end
end
if set then
for i = 1, 3 do
data.raw.technology["bi-tech-coal-processing-" .. i] = nil
BioInd.writeDebug("Removed technology " .. "bi-tech-coal-processing-" .. i)
end
end
-- Compatibility with Industrial Revolution
--require("prototypes.Industrial_Revolution")
------------------------------------------------------------------------------------
-- Add icons to our prototypes
BioInd.BI_add_icons()

123
Bio_Industries_2/data.lua Normal file
View file

@ -0,0 +1,123 @@
local BioInd = require('common')('Bio_Industries_2')
if not BI then BI = {} end
if not BI.Settings then BI.Settings = {} end
if not BI_Functions then BI_Functions = {} end
if not BI_Functions.lib then BI_Functions.lib = {} end
if not thxbob then thxbob = {} end
if not thxbob.lib then thxbob.lib = {} end
for var, name in pairs({
Bio_Cannon = "BI_Bio_Cannon",
BI_Bio_Fuel = "BI_Bio_Fuel",
BI_Easy_Bio_Gardens = "BI_Easy_Bio_Gardens",
BI_Bigger_Wooden_Chests = "BI_Bigger_Wooden_Chests",
BI_Game_Tweaks_Stack_Size = "BI_Game_Tweaks_Stack_Size",
BI_Game_Tweaks_Recipe = "BI_Game_Tweaks_Recipe",
BI_Game_Tweaks_Tree = "BI_Game_Tweaks_Tree",
BI_Game_Tweaks_Small_Tree_Collisionbox = "BI_Game_Tweaks_Small_Tree_Collisionbox",
BI_Game_Tweaks_Player = "BI_Game_Tweaks_Player",
BI_Game_Tweaks_Disassemble = "BI_Game_Tweaks_Disassemble",
BI_Game_Tweaks_Bot = "BI_Game_Tweaks_Bot",
BI_Solar_Additions = "BI_Solar_Additions"
}) do
BI.Settings[var] = BioInd.get_startup_setting(name)
end
--- Help Files
require("libs.item-functions") -- From Bob's Libary
require("libs.recipe-functions") -- From Bob's Libary
require("libs.technology-functions") -- From Bob's Libary
require("libs.functions") -- From Bob's Libary
require("libs.category-functions") -- From Bob's Libary
require("libs.bi_functions") -- Functions
require("prototypes.category")
--- Bio Farm
require("prototypes.Bio_Farm.entities")
require("prototypes.Bio_Farm.item")
require("prototypes.Bio_Farm.recipe")
require("prototypes.Bio_Farm.liquids")
require("prototypes.Bio_Farm.recipe-categories")
require("prototypes.Bio_Farm.pipeConnectors")
require("prototypes.Bio_Farm.technology")
require("prototypes.Bio_Farm.tree_entities")
-- Bio Garden
require("prototypes.Bio_Garden.entities")
require("prototypes.Bio_Garden.item")
require("prototypes.Bio_Garden.recipe")
require("prototypes.Bio_Garden.recipe-categories")
--- Bio Solar Farm
require("prototypes.Bio_Solar_Farm.entities")
require("prototypes.Bio_Solar_Farm.item")
require("prototypes.Bio_Solar_Farm.recipe")
--- Wood Products
require("prototypes.Wood_Products.entities")
require("prototypes.Wood_Products.item")
require("prototypes.Wood_Products.recipe")
require("prototypes.Wood_Products.containers-entities")
require("prototypes.Wood_Products.containers-item")
require("prototypes.Wood_Products.containers-recipe")
if not mods["Natural_Evolution_Buildings"] then
--- Dart Turret (Bio turret)
require("prototypes.Bio_Turret.item-group")
require("prototypes.Bio_Turret.damage-type")
require("prototypes.Bio_Turret.item")
require("prototypes.Bio_Turret.recipe")
require("prototypes.Bio_Turret.entity")
--- Bio Cannon
-- Items Groups
require("prototypes.Bio_Cannon.item-group")
-- Cannon
require("prototypes.Bio_Cannon.item")
require("prototypes.Bio_Cannon.recipe")
require("prototypes.Bio_Cannon.entity")
require("prototypes.Bio_Cannon.technology")
-- Projectiles
require("prototypes.Bio_Cannon.projectiles-item")
require("prototypes.Bio_Cannon.projectiles-recipe")
require("prototypes.Bio_Cannon.projectiles-entity")
end
---- Add Bio Fuel & Plastic, etc.
require("prototypes.Bio_Fuel.item")
require("prototypes.Bio_Fuel.recipe")
require("prototypes.Bio_Fuel.entities")
require("prototypes.Bio_Fuel.technology")
-- Create the hidden entities (Moved here so we can be sure the base
-- entities already exist and their properties can be read.)
require("prototypes.compound_entities.hidden_entities")
------------------------------------------------------------------------------------
-- Alien Biomes will degrade tiles to "landfill" if more than 255 tiles are defined
-- in the game. We can register the musk-floor tiles with Alien Biomes so it will
-- try to prioritize the tiles if they exist.
alien_biomes_priority_tiles = alien_biomes_priority_tiles or {}
table.insert(alien_biomes_priority_tiles, "bi-solar-mat")
------------------------------------------------------------------------------------
-- Add icons to our prototypes
BioInd.BI_add_icons()

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 785 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 944 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Some files were not shown because too many files have changed in this diff Show more