Project start

This commit is contained in:
Simon Brodtmann 2025-07-05 11:07:31 +02:00
parent 4b14645171
commit 3193b57ee5
968 changed files with 48029 additions and 0 deletions

View file

@ -0,0 +1,85 @@
----- Just used for Testing
function Test_Spawn()
local surface = game.surfaces['nauvis']
surface.create_entity({name = "tree-01", position = {2, 10}, force = game.forces.player})
surface.create_entity({name = "tree-02", position = {4, 10}, force = game.forces.player})
surface.create_entity({name = "tree-02-red", position = {6, 10}, force = game.forces.player})
surface.create_entity({name = "tree-03", position = {8, 10}, force = game.forces.player})
surface.create_entity({name = "tree-04", position = {10, 10}, force = game.forces.player})
surface.create_entity({name = "tree-05", position = {12, 10}, force = game.forces.player})
surface.create_entity({name = "tree-06", position = {14, 10}, force = game.forces.player})
surface.create_entity({name = "tree-06-brown", position = {16, 10}, force = game.forces.player})
surface.create_entity({name = "tree-07", position = {18, 10}, force = game.forces.player})
surface.create_entity({name = "tree-08", position = {20, 10}, force = game.forces.player})
surface.create_entity({name = "tree-08-brown", position = {22, 10}, force = game.forces.player})
surface.create_entity({name = "tree-09", position = {24, 10}, force = game.forces.player})
surface.create_entity({name = "tree-09-brown", position = {26, 10}, force = game.forces.player})
surface.create_entity({name = "tree-09-red", position = {28, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-a", position = {30, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-b", position = {32, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-c", position = {34, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-d", position = {36, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-e", position = {38, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-f", position = {40, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-g", position = {42, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-h", position = {44, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-i", position = {46, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-j", position = {48, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-k", position = {50, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-l", position = {52, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-m", position = {54, 10}, force = game.forces.player})
surface.create_entity({name = "tree-desert-n", position = {56, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-a", position = {58, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-b", position = {60, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-c", position = {62, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-d", position = {64, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-e", position = {66, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-f", position = {68, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-g", position = {70, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-h", position = {72, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-i", position = {74, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-j", position = {76, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-k", position = {78, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-l", position = {80, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-m", position = {82, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-n", position = {84, 10}, force = game.forces.player})
surface.create_entity({name = "tree-dryland-o", position = {86, 10}, force = game.forces.player})
--surface.create_entity({name = "tree-grassland-0", position = {88, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-a", position = {90, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-b", position = {92, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-c", position = {94, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-d", position = {96, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-e", position = {98, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-f", position = {100, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-g", position = {102, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-h", position = {104, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-h2", position = {106, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-h3", position = {108, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-i", position = {110, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-k", position = {112, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-l", position = {114, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-m", position = {116, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-n", position = {118, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-p", position = {120, 10}, force = game.forces.player})
surface.create_entity({name = "tree-grassland-q", position = {122, 10}, force = game.forces.player})
surface.create_entity({name = "tree-snow-a", position = {124, 10}, force = game.forces.player})
surface.create_entity({name = "tree-volcanic-a", position = {126, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-a", position = {128, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-b", position = {130, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-c", position = {132, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-d", position = {134, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-e", position = {136, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-f", position = {138, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-g", position = {140, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-h", position = {142, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-i", position = {144, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-j", position = {146, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-k", position = {148, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-l", position = {150, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-m", position = {152, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-n", position = {154, 10}, force = game.forces.player})
surface.create_entity({name = "tree-wetland-o", position = {156, 10}, force = game.forces.player})
end

43
Bio_Industries_2/_README Normal file
View file

@ -0,0 +1,43 @@
Feeling adventurous? Then check out the new Bio Cannon! Due to recent changes
in Factorio, it doesn't need any control scripting and should therefore be more
UPS friendly. As a bonus, you'll see the range when you hover the cursor over
the bio cannon -- just as with any vanilla turret. It also has a longer range
(120 instead of 90).
PLEASE NOTE: Factorio >=0.18.33 is required for this! Otherwise, it may happen
that you waste your expensive ammo on a single biter/spitter.
control_bio_cannon.lua.18.33
control.lua.18.33
data-final-fixes.lua.18.33
prototypes/Bio_Cannon/entity.lua.18.33
prototypes/Bio_Cannon/item-group.lua.18.33
prototypes/Bio_Cannon/item.lua.18.33
prototypes/Bio_Cannon/recipe.lua.18.33
They make the old, combined entity for the Bio Cannon redundant, but as
attack_target_mask can't be used to limit what entities will be attacked
in earlier versions of Factorio, these files aren't officially active yet.
If you want to try out the new Bio Cannon, replace each of these files:
control_bio_cannon.lua
control.lua
data-final-fixes.lua
prototypes/Bio_Cannon/entity.lua
prototypes/Bio_Cannon/item-group.lua
prototypes/Bio_Cannon/item.lua
prototypes/Bio_Cannon/recipe.lua
with its counterpart listed above! I've already made a backup of the original
files, so if it doesn't work, just replace the new files with the *.bak version!
Does the new Bio Cannon work as expected? Is the new range OK? (Please keep in
mind that this is the "prototype artillery": It should be weaker than the
vanilla artillery turrets, so extending the range even more probably is not a
good idea.) Your feedback is very appreciated and will hopefully help to get
the new Bio Cannon bug-free in time for Factorio 1.0!

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,29 @@
prototypes/Bio_Cannon/recipe.lua
prototypes/Bio_Cannon/projectiles-recipe.lua
prototypes/Bio_Farm/recipe.lua
prototypes/Bio_Farm/compatible_recipes.lua
prototypes/Bio_Farm/technology.lua
prototypes/Bio_Fuel/recipe.lua
prototypes/Bio_Garden/recipe.lua
prototypes/Bio_Solar_Farm/recipe.lua
prototypes/Bio_Turret/recipe.lua
prototypes/Wood_Products/recipe.lua
data-updates.lua:
- Moved disassemble recipes and recipe tweaks to this file
- Moved require("prototypes.Wood_Products.rail_updates") to this file
data-final-fixes.lua:
- Removed disassemble recipes and recipe tweaks!
- Removed require("prototypes.Wood_Products.rail_updates") s
prototypes/Bio_Solar_Farm/entities.lua:
- Increased supply_area_distance from 50 to 50.5 to fix that half tiles would be covered at the edge of the radius visualisation

871
Bio_Industries_2/common.lua Normal file
View file

@ -0,0 +1,871 @@
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.Version.compare = function(mod_name, operator, need_version)
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 = {"floor-layer", "object-layer", "consider-tile-transitions"}
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")
--~ log("common.RAIL_BRIDGE_MASK: " .. serpent.block(common.RAIL_BRIDGE_MASK))
--~ log("common.RAIL_MASK: " .. serpent.block(common.RAIL_MASK))
------------------------------------------------------------------------------------
-- 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()
--~ log("Entered function get_tree_ignore_list!")
local ignore = {}
local trees = game and
game.get_filtered_entity_prototypes({{filter = "type", type = "tree"}}) or
data.raw.tree
for tree_name, tree in pairs(trees) do
--~ log("tree_name: " .. tree_name)
for p, pattern in ipairs(common.ignore_name_patterns) do
--~ log("Check for match against pattern " .. pattern)
if tree_name:match(pattern) then
--~ log("Pattern matches!")
ignore[tree_name] = true
break
end
end
end
--~ log("Tree ignore list (" .. table_size(ignore) .. "): " .. serpent.block(ignore))
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
--~ ------------------------------------------------------------------------------------
--~ -- Set some values for Musk floor tiles (bi-solar-mat), so we can use these with
--~ -- confidence when filtering for the prototype
--~ common.MUSK_FLOOR_walking_speed_modifier = 1.45
--~ common.MUSK_FLOOR_decorative_removal_probability = 1
------------------------------------------------------------------------------------
-- 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 name .. " (" .. tostring(id) .. ")"
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
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 = game.item_prototypes["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()
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 = {}
local h_type
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 game.entity_prototypes[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
--~ h_type = common.HE_map[h_key]
common.writeDebug("h_key: %s\th_data: %s", {h_key, h_data})
-- Remove hidden entity if it doesn't exist
if not game.entity_prototypes[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})
global[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 global[%s] (%s values)", {tab, table_size(global[tab])})
global[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 global[%s] (was: %s)",
{var_name, var_name and global[var_name] or "nil"})
global[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 global.compound_entities[base.name]) then
common.arg_err(base, "base of a compound entity")
end
-- Add optional values to global table
local data = global.compound_entities[base.name]
common.show("data", data)
local tab = data.tab
common.show("tab", tab)
common.show("global[tab]", global[tab] or "nil")
local entry = global[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(global.compound_entities[entity_name])})
--~ local entity_table = global[common.compound_entities[entity_name].tab]
--~ local hidden_entities = common.compound_entities[entity_name].hidden
local entity_table = global.compound_entities[entity_name]
common.show("entity_table", entity_table and entity_table.tab)
entity_table = entity_table and entity_table.tab and global[entity_table.tab]
common.writeDebug("entity_table: %s", {entity_table}, "line")
local hidden_entities = global.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))
--~ common.show("Pruned list", 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("global.compound_entities[%s]: %s", {entity_name, global.compound_entities[entity_name]})
common.writeDebug("global.compound_entities[%s]: %s entries", {entity_name, table_size(global.compound_entities[entity_name])})
local check = global.compound_entities[entity_name]
local entity_table = check and global[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
--~ common.writeDebug("c: %s\tcompound: %s", {c, compound})
-- 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
--~ common.writeDebug("h_name: %s\th_entity: %s", {h_name, h_entity})
-- 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
--~ common.writeDebug("Restored %s %s", {entity_name, c})
end
end
common.writeDebug("Checked %s compound entities", {checked})
common.writeDebug("Restored %s entities", {restored})
--~ common.show("Fixed list", entity_table)
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 = global.compound_entities[compound_name]
if not data then
common.arg_err(compound_name, "name of a compound entity")
end
local g_tab = global[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(global.compound_entities) do
cnt = cnt + common.register_in_compound_entity_tab(compound_entity)
end
--~ common.writeDebug("Registered %s compound entities", {cnt})
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)
surface = (t == "number" or t == "string" and game.surfaces[surface]) or
(t == "table" and surface.object_name and
surface.object_name == "LuaSurface" and surface)
return surface
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_entity_names, position, ...)
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.show("hidden_entities", hidden_entities)
common.check_args(g_table, "table")
common.check_args(base_entity, "table")
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 = common.compound_entities[base_entity.name].hidden[key]
data = global.compound_entities[base_entity.name].hidden[key]
--~ common.show("common.compound_entities[base_entity.name].hidden",
--~ common.compound_entities[base_entity.name].hidden)
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
--~ local optional = global.compound_entities[base_entity.name].optional
--~ for k, v in pairs(optional or {}) do
--~ g_table[base_entity.unit_number][k] = v
--~ end
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 = {}
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 = game.get_filtered_entity_prototypes({
{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 = global.compound_entities["bi-bio-garden"]
--~ local pole_type = "electric-pole"
--~ local pole = global[compound_entity.tab][base.unit_number] and
--~ global[compound_entity.tab][base.unit_number][pole_type] or
--~ new_pole
local pole = global[compound_entity.tab][base.unit_number] and
global[compound_entity.tab][base.unit_number].pole or
new_pole
--~ if pole and pole.valid then
--~ local wire_reach = game.entity_prototypes[compound_entity.hidden[pole_type]] and
--~ game.entity_prototypes[compound_entity.hidden[pole_type]].max_wire_distance
if pole and pole.valid and compound_entity.hidden and
compound_entity.hidden.pole and
compound_entity.hidden.pole.name then
local wire_reach = game.entity_prototypes[compound_entity.hidden.pole.name] and
game.entity_prototypes[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
--~ -- Connect hidden poles to other poles that may be in reach.
--~ common.garden_pole_connectors = common.garden_pole_connectors and next() or
--~ common.get_garden_pole_connectors()
--~ common.show("Poles hidden bio-garden poles may connect to", global.mod_settings.garden_pole_connectors)
-- Look for other poles around this one
neighbours = pole.surface.find_entities_filtered({
position = pole.position,
radius = wire_reach,
type = "electric-pole",
name = global.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_type = "electric-pole"
local pole = global.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 global.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
--~ common.writeDebug("Checking data.raw[%s]", {tab_name})
for proto_type_name, proto_type in pairs(data.raw[tab_name] or {}) do
--~ common.show("proto_type.BI_add_icon", proto_type.BI_add_icon or "nil" )
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

1095
Bio_Industries_2/control.lua Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,270 @@
--~ local BioInd = require("__" .. script.mod_name .. "__.common")(script.mod_name)
BioInd.writeDebug("Entered control_arboretum.lua")
---Arboretum Stuff
--~ local Event = require('__stdlib__/stdlib/event/event').set_protected_mode(true)
local Event = require('__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 = {
--~ ["landfill"] = true,
["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 = {
--~ ["landfill"] = true,
["grass-1"] = true, -- Fertility: 100%
["vegetation-green-grass-1"] = true, -- Fertility: 100%
}
local plant_radius = 75
--~ local plant_radius = 25
-- 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 OmniFluid
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()
local need = recipe and global.bi_arboretum_recipe_table[recipe.name]
local function check(need, have)
for name, amount in pairs(need or {}) do
if not (have and have[name]) or (have[name] < amount) then
BioInd.writeDebug("Missing ingredient %s (have %s of %s)", {name, have[name] or 0, amount})
return false
end
end
return true
end
local inventory = arboretum.get_inventory(defines.inventory.assembling_machine_input)
return need and
check(need.items, inventory and inventory.get_contents()) and
check(need.fluids, arboretum.get_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, can_be_placed
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 = global.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")
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
ingredients, recipe_name = check.ingredients, check.name
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,669 @@
--~ local BioInd = require("__"..script.mod_name.."__.common")(script.mod_name)
-- All tree Growing stuff
local Event = require('__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,
}
--~ local function get_tile_fertility(surface, position)
--~ 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")
--~ local fertility = Bi_Industries.fertility[surface.get_tile(position.x, position.y).name]
--~ return fertility and {fertility = fertility, key = "fertilizer"} or
--~ {fertility = 1, key = "default"}
--~ end
-- 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, tree)
--~ table.sort(tabl, function(a, b) return a.time < b.time end)
--~ table.sort(tabl, function(a, b) return a.time > b.time end)
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(global.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(surface, position)
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 (game.item_prototypes[stage_1_tree_name] or
game.entity_prototypes[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(global.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 (game.item_prototypes[next_stage_tree_name] or
game.entity_prototypes[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(global.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 global.bi.tree_growing_stage_1 == nil then
for i = 1, 4 do
global.bi["tree_growing_stage_"..i] = global.bi["tree_growing_stage_"..i] or {}
end
end
local tick = event.tick
if global.bi.tree_growing[tick] then
for t, tree_data in pairs(global.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 global.bi.tree_growing[%s]!", {tick})
global.bi.tree_growing[tick] = nil
end
local stage_table
for stage = 1, 4 do
stage_table = global.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 global.bi.tree_growing_stage_%s[%s]!",
{stage, tick})
stage_table[tick] = nil
end
end
end)

View file

@ -0,0 +1,33 @@
-------------------------------------------------------------------------------
------------------------------------- Credits ---------------------------------
-------------------------------------------------------------------------------
L0771 - For his help given to me to start this MOD.
AlyxDeLunar - For his MOD Dynamic Expansion that I've used in my MOD.
Albatrosv13 - For his MOD Alien Temple that I've used in my MOD.
FreeER - For his MOD Mind Control that I've used in my MOD.
Darkshadow1809 - For his Evolution MOD .
Rsending91, DOSorDIE and SpeedyBrain - Item/Corpse Collector Mod.
Orzelek - RSO, Coding help and answering questions!
Veden - He added some amazing code to my mod and has an amazing AI behavior mod: Rampant. Must have!
ThaPear, Semvoz, Billw, Adil, Rseding91, Chlue - Coding help!
Supercheese - Swarm Mod.
Afforess - Misanthrope Mod.
Darkfrei - Help with the solar-mat & tree stuff. Graphics and so much more!
d3x0r - Wooden Rail Bridge images and rail work in general
drs9999 - Tree Farm Mod
S_R_G - Graphics
Steinio - Use of his "steinios unlasting oil" mod.
DellAquila - Use of his "FiniteWater" mod
Eradicator - Lot of help on the forums
Veni - A lot of help with the Bio-Fuel section
SpeedDaemon - Greenhouse Mod
Simdezimon - Wood Floors
Klonan - Big Wooden Pole and Wooden Fence
LukeM212 & JJtJJ - Tree Mods
DySoch - DyTech, showing me what was possible
Bobingabout - Bob's Mods - Learned a lot from looking at your amazing work and am using a lot of your great code!
YuokiTani - Art!! Amazing work!
And everyone else who give feedback/suggestions/help on the forums!
Sorry if I missed anyone! PM me!!

View file

@ -0,0 +1,534 @@
local BioInd = require('common')('Bio_Industries')
local ICONPATH = "__Bio_Industries__/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
-- Moved to data-updates.lua for 0.18.34/1.1.4!
--~ ---- 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 (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.add_new_ingredient("rail", {type = "item", name = "concrete", amount = 6})
--~ end
---- 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 = {
--~ {
--~ type = "item",
--~ name = "wood",
--~ amount_min = 1,
--~ amount_max = 6
--~ }
--~ }
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
--~ BioInd.show("tree.minable", tree.minable)
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
--~ BioInd.show("w_pattern", w_pattern)
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
--~ BioInd.show("b_pattern", b_pattern)
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
-- Moved to data-updates.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
---- 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)
-- Changed for 0.18.34/1.1.4!
--~ if not bot.flags then
--~ bot.flags = {}
--~ end
--~ if not bot.resistances then
--~ bot.resistances = {}
--~ end
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,
-- Removed in 0.17.48/0.18.16
--~ ["thorium-fuel-cell"] = 5.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"] 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",
}
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" then
krastorio.recipes.multiplyIngredients(recipe.name, update, 4)
krastorio.recipes.multiplyProducts(recipe.name, update, 4)
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 = { "water-tile" }
}
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 = { "water-tile" }
}
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
-- Moved to data-updates.lua for 0.18.34/1.1.4!
--~ -- "Transport drones" ruins rails by removing object-layer from the collision mask. That
--~ -- causes problems for our "Wooden rail bridges" as they will also pass through cliffs.
--~ -- Fix the collision masks for rail bridges if "Transport drones" is active!
--~ if mods["Transport_Drones"] then
--~ for _, type in pairs({"straight-rail", "curved-rail"}) do
--~ data.raw[type]["bi-" .. type .. "-wood-bridge"].collision_mask = BioInd.RAIL_BRIDGE_MASK
--~ end
--~ end
--~ require("prototypes.Wood_Products.rail_updates")
--- 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["curved-rail"]) do
--~ log(v.name)
--~ end
--~ for k,v in pairs(data.raw["straight-rail"]) do
--~ log(v.name)
--~ end
--~ for k,v in pairs(data.raw["rail-planner"]) do
--~ log(v.name)
--~ end
--~ BioInd.writeDebug("Testing at end of data-final-fixes.lua!")
--~ for rail_name, rail in pairs(data.raw["straight-rail"]) do
--~ BioInd.show("rail_name", rail_name)
--~ BioInd.show("flags", rail.flags)
--~ BioInd.show("fast_replaceable_group", rail.fast_replaceable_group)
--~ BioInd.show("next_upgrade", rail.next_upgrade)
--~ BioInd.show("bounding_box", rail.bounding_box)
--~ BioInd.show("collision_mask", rail.collision_mask)
--~ end
--~ for r, recipe in pairs(data.raw.recipe) do
--~ if r:match("^.*boiler.*$") then
--~ BioInd.writeDebug("recipe: %s\torder: %s\tsubgroup: %s", {r, recipe.order or "", recipe.subgroup or "" })
--~ end
--~ end
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,825 @@
local BioInd = require('common')('Bio_Industries')
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("data.raw.recipe[\"bi-sulfur\"]", data.raw.recipe["bi-sulfur"])
BioInd.show("BI.Settings.BI_Easy_Bio_Gardens", BI.Settings.BI_Easy_Bio_Gardens)
local ICONPATH = "__Bio_Industries__/graphics/icons/"
----Update the Wood Pipe Images
require("prototypes.Wood_Products.pipes")
--- Update the images of Wooden rail bridges and their remnants
require("prototypes.Wood_Products.wooden_rail_bridge_update")
--~ --- Bridge Rail Remnants
--~ require("prototypes.Wood_Products.update_bridge_rails_remnants")
require("prototypes.Wood_Products.tint_rails_remnants_function")
-- Concrete Rail
---- Update Standard Rails to use and look like concrete
set_tint_to_rails(
{
data.raw["straight-rail"]["straight-rail"],
data.raw["curved-rail"]["curved-rail"]
},
{r = 183/255, g = 183/255, b = 183/255, a = 1}
) -- concrete
set_tint_to_remnants(
{
data.raw["rail-remnants"]["straight-rail-remnants"],
data.raw["rail-remnants"]["curved-rail-remnants"]
},
{r = 183/255, g = 183/255, b = 183/255, a = 1}
) -- concrete
-- Wood Rail
set_tint_to_rails(
{
data.raw["straight-rail"]["bi-straight-rail-wood"],
data.raw["curved-rail"]["bi-curved-rail-wood"]
},
{r = 183/255, g = 125/255, b = 62/255, a = 1}
) -- wood
set_tint_to_remnants(
{
data.raw["rail-remnants"]["straight-rail-remnants-wood"],
data.raw["rail-remnants"]["curved-rail-remnants-wood"]
},
{r = 183/255, g = 125/255, b = 62/255, a = 1}
) -- wood
--- Power Rail
set_tint_to_rails(
{
data.raw["straight-rail"]["straight-rail"],
data.raw["curved-rail"]["curved-rail"]
},
{r = 150/255, g = 150/255, b = 150/255, a = 1}
) -- mix
-- vanilla rail icon & images update
data.raw["straight-rail"]["straight-rail"].icon = ICONPATH .. "straight-rail-concrete.png"
data.raw["straight-rail"]["straight-rail"].icon_size = 64
data.raw["straight-rail"]["straight-rail"].icon_mipmaps = 4
data.raw["curved-rail"]["curved-rail"].icon = ICONPATH .. "curved-rail-concrete.png"
data.raw["curved-rail"]["curved-rail"].icon_size = 64
data.raw["curved-rail"]["curved-rail"].icon_mipmaps = 4
data.raw["rail-planner"]["rail"].icon = ICONPATH .. "rail-concrete.png"
data.raw["rail-planner"]["rail"].icon_size = 64
data.raw["rail-planner"]["rail"].icon_mipmaps = 4
--- Wood Rail added to Tech
thxbob.lib.tech.add_recipe_unlock("railway", "bi-rail-wood")
--- If Bob, move Vanilla Rail to Rail 2, also add Power Rail.
if data.raw.technology["bob-railway-2"] then
thxbob.lib.tech.remove_recipe_unlock ("railway", "rail")
thxbob.lib.tech.add_recipe_unlock("bob-railway-2", "rail")
thxbob.lib.tech.add_recipe_unlock("bob-railway-2", "bi-rail-wood-to-concrete")
thxbob.lib.tech.add_recipe_unlock("bob-railway-2", "bi-rail-wood-bridge")
thxbob.lib.tech.add_recipe_unlock("bob-railway-2", "bi-rail-power")
thxbob.lib.tech.add_recipe_unlock("bob-railway-2", "bi-power-to-rail-pole")
else
thxbob.lib.tech.add_recipe_unlock("railway", "bi-rail-wood-to-concrete")
thxbob.lib.tech.add_recipe_unlock("rail-signals", "bi-rail-wood-bridge")
thxbob.lib.tech.add_recipe_unlock("rail-signals", "bi-rail-power")
thxbob.lib.tech.add_recipe_unlock("rail-signals", "bi-power-to-rail-pole")
end
-- 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")
--~ thxbob.lib.tech.add_prerequisite("advanced-material-processing-2", "concrete")
-- 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
--~ if mods["IndustrialRevolution"] then
--~ -- Our large wooden poles are unlocked by the "Logistics" research and require small
--~ -- electric poles, which are unlocked by IR2 after the Iron Age has been reached. So,
--~ -- if IR2 is active, we won't unlock our poles and use IR2's large wooden poles for
--~ -- our huge poles instead.
--~ local big_pole = "bi-wooden-pole-big"
--~ thxbob.lib.tech.add_recipe_unlock ("electric-energy-distribution-1", big_pole)
--~ thxbob.lib.tech.add_recipe_unlock ("electric-energy-distribution-2", "bi-wooden-pole-huge")
--~ -- Adjust localizations
--~ for k, v in ipairs({"electric-pole", "item", "recipe"}) do
--~ BioInd.show("Changing localization for", v)
--~ data.raw[v][big_pole].localised_name = {"entity-name.bi-wooden-pole-bigger"}
--~ data.raw[v][big_pole].localised_description = {"entity-description.bi-wooden-pole-bigger"}
--~ end
--~ else
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")
--~ end
--- 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 = { "water-tile" }
}
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")
--~ thxbob.lib.tech.add_recipe_unlock("bob-solar-energy-2", "bi-solar-boiler")
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")
--~ thxbob.lib.tech.add_recipe_unlock("solar-energy", "bi-solar-boiler")
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}
)
--~ thxbob.lib.recipe.remove_ingredient ("bi-solar-boiler", "boiler")
--~ thxbob.lib.recipe.add_new_ingredient ("bi-solar-boiler", {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-bio-reactor")
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-1", "bi-basic-gas-processing")
thxbob.lib.tech.add_recipe_unlock("bi-tech-coal-processing-2", "bi-basic-gas-processing")
--~ -- Blacklist bioreactor in Assembler Pipe Passthrough
--~ if mods["assembler-pipe-passthrough"] then
--~ appmod.blacklist['bi-bio-reactor'] = true
--~ end
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
--~ thxbob.lib.recipe.add_new_ingredient("bi-adv-fertilizer-1", {type = "fluid", name = "bi-biomass", amount = 10})
--~ thxbob.lib.recipe.add_new_ingredient("bi-adv-fertilizer-2", {type = "fluid", name = "bi-biomass", amount = 10})
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 = { "water-tile" }
}
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_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_bio_seed2.png"
data.raw.recipe["bi-seed-2"].icon_size = 64
data.raw.recipe["bi-seedling-2"].icon = ICONPATH .. "py_Seedling2.png"
data.raw.recipe["bi-seedling-2"].icon_size = 64
data.raw.recipe["bi-logs-2"].icon = ICONPATH .. "py_raw-wood-mk2.png"
data.raw.recipe["bi-logs-2"].icon_size = 64
data.raw.recipe["bi-ash-1"].icon = ICONPATH .. "py_ash_raw-wood.png"
data.raw.recipe["bi-ash-1"].icon_size = 64
data.raw.recipe["bi-ash-2"].icon = ICONPATH .. "py_ash_woodpulp.png"
data.raw.recipe["bi-ash-2"].icon_size = 64
data.raw.recipe["bi-stone-brick"].icon = ICONPATH .. "py_bi_stone_brick.png"
data.raw.recipe["bi-stone-brick"].icon_size = 64
--~ data.raw.recipe["bi-sulfur"].icon = ICONPATH .. "py_bio_sulfur.png"
--~ data.raw.recipe["bi-sulfur"].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 mod_list = {"angelspetrochem", "Krastorio", "Krastorio2", "pyrawores"}
--~ local check = true
--~ for for m, mod_name in ipairs(mod_list) do
--~ if mod[mod_name] then
--~ check = false
--~ break
--~ else
--~ BioInd.writeDebug("Check passed: %s is not active", mod_name)
--~ end
--~ end
--~ if not (mods["angelspetrochem"] or mods["Krastorio"] or mods["Krastorio2"] or mods["pyrawores"]) then
--~ if check then
--~ BioInd.writeDebug("We can create the fluids now, if we need to!")
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,
order = "a[fluid]-b[nitrogen]"
},
})
--~ BI_Functions.lib.allow_productivity("bi-nitrogen")
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,
order = "a[fluid]-b[liquid-air]"
},
})
--~ BI_Functions.lib.allow_productivity("bi-liquid-air")
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 (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.add_new_ingredient("rail", {type = "item", name = "concrete", amount = 6})
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
--~ BioInd.writeDebug("h_type: %s\th_name: %s\th:%s", {h_type, h_name, h})
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
-- Moved here from data-final-fixes.lua for 0.18.34/1.1.4! (Fixes https://mods.factorio.com/mod/Bio_Industries/discussion/5ff517c391699300236170a2)
-- "Transport drones" ruins rails by removing object-layer from the collision mask. That
-- causes problems for our "Wooden rail bridges" as they will also pass through cliffs.
require("prototypes.Wood_Products.rail_updates")
-- Compatibility with Industrial Revolution
require("prototypes.Industrial_Revolution")
------------------------------------------------------------------------------------
-- Add icons to our prototypes
BioInd.BI_add_icons()

137
Bio_Industries_2/data.lua Normal file
View file

@ -0,0 +1,137 @@
local BioInd = require('common')('Bio_Industries')
if not BI then BI = {} end
if not BI.Settings then BI.Settings = {} end
--~ if not BI_Config then BI_Config = {} end
--~ if not BI_Config.mod then BI_Config.mod = {} 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
--~ BioInd.show("BI.Settings.BI_Easy_Bio_Gardens", BI.Settings.BI_Easy_Bio_Gardens)
--~ BioInd.show("BI.Settings.BI_Game_Tweaks_Disassemble", BI.Settings.BI_Game_Tweaks_Disassemble)
--- 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")
--~ -- Create the hidden entities
--~ require("prototypes.compound_entities.hidden_entities")
--~ BioInd.show("BioInd.compound_entities", BioInd.compound_entities)
--~ error("Break!")
--- 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")
--~ for i, item in pairs(data.raw.item) do
--~ BioInd.show("Item", i)
--~ end
------------------------------------------------------------------------------------
-- Add icons to our prototypes
BioInd.BI_add_icons()

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: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 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: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

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