Aleksei-bird 7c9c708c92 Первый фикс
Пачки некоторых позиций увеличены
2024-03-01 20:54:33 +03:00

642 lines
21 KiB
Lua

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
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
-- Update table
table.insert(tabl, tree)
table.sort(tabl, function(a, b) return a.time < b.time end)
-- 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 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
function random_tree(surface, position)
surface = BioInd.is_surface(surface) or BioInd.arg_err(surface or "nil", "surface")
position = position and BioInd.normalize_position(position) or
BioInd.arg_err(position or "nil", "position")
local tile_name = surface.get_tile(position.x, position.y).name
BioInd.show("random_tree: tile_name", tile_name)
BioInd.show("terrains[tile_name]", terrains[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. trees_table: %s\tmax_index: %s", {tile_name,trees_table, 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 or "nil", tree2 or "nil", tree3 or "nil"})
-- fertility will be 1 if terrain type is not listed above, so very small chance to grow.
local f = get_tile_fertility(surface, position)
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)
BioInd.show("tree_name", tree_name)
end
if tree and tree_name and not seed_bomb then
BioInd.writeDebug("tree and not seed_bomb")
tree.destroy()
BioInd.writeDebug("Destroyed tree!")
--- Depending on Terrain, choose tree type & Convert seedling into a tree
if key == "fertilizer" then
BioInd.writeDebug("New tree can grow!")
-- Grow the new tree
can_be_placed = surface.can_place_entity({
name = tree_name, position = position, force = "neutral"
})
if tree_name and 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.writeDebug("grow_time: %s", {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
if tree_name and tree2 or tree3 then
if tree2 then tree2.destroy() end
if tree3 then tree3.destroy() end
--- Depending on terrain, choose tree type & convert seedling into a tree
if key == "fertilizer" then
can_be_placed = surface.can_place_entity{
name = tree_name,
position = position,
force = "neutral"
}
if can_be_placed and tree_name and growth_chance <= fertility then
surface.create_entity{
name = tree_name,
position = position,
force = "neutral"
}
end
end
end
if seed_bomb then
BioInd.writeDebug("Seed bomb was used!")
if tree then
tree.destroy()
end
--- Depending on Terrain, choose tree type & Convert seedling into a tree
if key == "fertilizer" then
BioInd.writeDebug("Got Tile")
if tree_name then
BioInd.writeDebug("Found Tree")
can_be_placed = surface.can_place_entity({
name = tree_name, position = position, force = "neutral"
})
if can_be_placed and growth_chance <= fertility then
surface.create_entity{name = tree_name, position = position, force = "neutral"}
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] = {}
end
end
while next(global.bi.tree_growing) do
-- Table entries are sorted by "time", so we can stop if the first entry's
-- "time" refers to a tick in the future!
if event.tick < global.bi.tree_growing[1].time then
--~ BioInd.writeDebug("Still growing")
break
end
--~ BioInd.writeDebug("Not growing! Calling Grow_tree_stage_0")
Grow_tree_first_stage(global.bi.tree_growing[1], event)
table.remove(global.bi.tree_growing, 1)
--~ BioInd.writeDebug("global.bi.tree_growing: %s", {global.bi.tree_growing}, "line")
end
for stage = 1, 4 do
local stage_table = global.bi["tree_growing_stage_" .. stage]
while next(stage_table) do
if event.tick < stage_table[1].time then
break
end
Grow_tree_stage(stage_table[1], stage)
table.remove(stage_table, 1)
end
end
end)