Factorio-Farming-Mod/control.lua
2024-11-27 16:56:11 -05:00

415 lines
11 KiB
Lua

local flib_position = require("__TEST__/depends/flib/position");
local fun = require("__TEST__/depends/luafun/fun");
local control_const = require("controlconst");
local autotill_target = (require("prototypes/const")).Auto_till_target * 1000;
local lib = require("prototypes/lib");
script.on_init(function()
global.myData = {};
global.registeredEntities = {};
global.onDestroyRegistry = {};
global.endStageCrops = {};
global.myData = {};
global.tileData = {};
end);
local exchange = {};
local plantSeeds = {
"wheat-1"
};
local endStageCropNames = {
"wheat-4"
};
local harvestFunctions = {
["wheat-4"] = function(entity)
return {
return_item = {
count = math.random(0, 5),
name = "wheat-1"
}
};
end
};
function Get_tiledata_from_position(positon)
local floored = flib_position.floor(positon);
local starty = floored.y;
local startx = floored.x;
local output = {};
for posx in fun.range(-16, 16) do
local posx = posx + startx;
local row = global.tileData[posx];
if row == nil then
global.tileData[posx] = {};
end;
for posy in fun.range(-16, 16) do
table.insert(output, {
posx * 32,
posy * 32
});
end;
end;
end;
function base_generation(x, a, b, c, w)
return (c * (((math.pi / (w * 100)) * x + b) ^ 2) + a)
end;
function Gen_Sulfer(elevation)
local a = 8.3;
local b = 0.1;
local c = -13.9;
local w = 6.3;
return base_generation(elevation, a, b, c, w) * 10;
end;
function Gen_Nitrogen(elevation)
local a = -6.2;
local b = -0.4;
local c = -1;
local w = 2.6;
return base_generation(elevation, a, b, c, w) * -42;
end;
function Gen_Calcium(elevation)
local a = 55;
local b = -1;
local w = -0.2;
local c = -0.2;
return base_generation(elevation, a, b, c, w);
end;
function Gen_potassium_elevation(elevation)
local a = 83;
local b = -2;
local c = 6.2;
local w = 0.6;
return base_generation(elevation, a, b, c, w);
end;
function Gen_potassium_moisture(moisture)
local a = -2.6
local b = 4.2
local c = 0.55
return (a * moisture ^ 2 + b * moisture) + c
end
function Temp_Bonus(temprature)
--the logic behind this piecewise function is, really above everything else
--fertility correlates wirh temprature. Most life is optimized for between 5c and 22c noon temp
--esp plant life. And, macronutrients agrigrate over time around plants because they soak them up like sponges
--its not equal, the game ranges between -20 and 50 c, but life peaks at 22 and by the time you hit 30 you're way too hot
if temprature >= 22 then
local a = 5.46
local b = 0.3
local c = -10
local w = 0.9
local bonus = base_generation(temprature, a, b, c, w)
return bonus
else
local a = 3.3
local b = -0.9
local c = -5
local w = 0.83
local bonus = base_generation(temprature, a, b, c, w)
return bonus
end
end
function Gen_Soil_Data(calculations)
local temperature = calculations.temperature[1];
local elevation = calculations.elevation[1];
local moisture = calculations.moisture[1];
-- TOOD: figuroue wtf is happening with this function
--local tempratureBonus = Temp_Bonus(temperature)
local sulfer = Gen_Sulfer(elevation)
local calcium = Gen_Calcium(elevation)
local nitrogen = Gen_Nitrogen(elevation)
local potassium_moisture = Gen_potassium_moisture(moisture)
local potassium = Gen_potassium_elevation(elevation) * potassium_moisture
local ref = { sulfer, calcium, nitrogen, potassium }
for i, value in pairs(ref) do
if 0 > value then
--idk if this works
ref[i] = 0.1
end
end
local moisture = Gen_potassium_elevation(moisture)
game.print("in: " .. temperature .. ", " .. elevation .. ", " .. moisture);
game.print("out: " .. sulfer .. ", " .. calcium .. ", " .. nitrogen .. ", " .. potassium);
end;
local function get_xy(point)
local x = point % 2 ^ 26;
local y = (point - x) / 2 ^ 26;
return {
x = x - 2 ^ 25,
y = y - 2 ^ 25
};
end;
local function get_point(position)
return position.x + 2 ^ 25 + (position.y + 2 ^ 25) * 2 ^ 26;
end;
function Replace_entity(name, surface, registered)
local entity = registered.entity;
exchange[name] = registered.state;
local created = surface.create_entity({
name = name,
position = entity.position,
fast_replace = true
});
entity.destroy();
return created;
end;
local test = nil;
function Make_wheat_grow(surface, data)
local rand = math.random(0, 50);
local name = data.entity.name;
if rand == 0 then
if name == "wheat-1" then
return {
end_life = true,
replace = "wheat-2"
};
elseif name == "wheat-2" then
return {
end_life = true,
replace = "wheat-3"
};
elseif name == "wheat-3" then
return {
end_life = true,
replace = "wheat-4"
};
end;
end;
return {
end_life = false,
replace = nil
};
end;
function Empty_init(entity, previous_state)
return previous_state;
end;
local wheatObj = {
init = Empty_init,
iterate = Make_wheat_grow
};
local init = -1;
function temp_init(entity, previous_state)
init = init + 1;
return {
our_value = init
};
end;
function EmptyIterate(surface, data)
return {
end_life = true
};
end;
local registeredEntityCallbacks = {
["wheat-1"] = {
init = temp_init,
iterate = Make_wheat_grow
},
["wheat-2"] = wheatObj,
["wheat-3"] = wheatObj,
["wheat-4"] = {
init = Empty_init,
iterate = EmptyIterate
},
pre_soil_ore = {
init = function(entity, previous_state)
entity.amount = 1;
return {};
end
},
["auto-till"] = {
iterate = function(surface, data)
if data.entity.energy == autotill_target then
local tiles = surface.find_tiles_filtered({
name = control_const.natural_tiles_walkable,
position = data.entity.position,
radius = 6,
limit = 4
});
local output = {};
for _, tile in ipairs(tiles) do
local newTile = {
name = "soil",
position = tile.position
};
table.insert(output, newTile);
end;
surface.set_tiles(output);
return {
end_life = true
};
end;
return {
end_life = false
};
end,
init = Empty_init
},
harvester = {
init = function(entity, previous_state)
local input = entity.get_inventory(defines.inventory.chest);
return {};
end,
iterate = function(surface, data)
local output = data.entity.get_inventory(defines.inventory.chest);
local foundCrops = surface.find_entities_filtered({
position = data.entity.position,
radius = 6,
name = endStageCropNames
});
for i, entity in ipairs(foundCrops) do
local result = harvestFunctions[entity.name](entity);
if result.return_item ~= nil and result.return_item.count > 0 then
output.insert(result.return_item);
end;
entity.destroy();
end;
return {
end_life = false,
replace = nil
};
end
},
planter = {
init = function(entity, previous_state)
return {};
end,
iterate = function(surface, data)
local output = data.entity.get_inventory(defines.inventory.chest);
if not output.is_empty() then
local contents = output.get_contents();
local seeds = fun.totable(fun.filter(function(key, value)
local isSeed = fun.index(key, plantSeeds);
return isSeed ~= nil;
end, contents));
if #seeds > 0 then
local tiles = surface.find_tiles_filtered({
name = "soil",
position = data.entity.position,
radius = 6
});
local hasNoEntities = fun.totable(fun.filter(function(tile)
local entities = surface.find_entities_filtered({
position = tile.position,
radius = 1,
limit = 1
});
return #entities == 0;
end, tiles));
for i, tile in pairs(hasNoEntities) do
local seedType = seeds[math.random(1, #seeds)];
if contents[seedType] ~= 0 then
local created = surface.create_entity({
name = seedType,
position = tile.position,
fast_replace = true
});
end;
end;
end;
end;
return {
end_life = false,
replace = nil
};
end
}
};
script.on_event(defines.events.on_player_changed_position, function(event)
local myData = global.myData;
local player = game.get_player(event.player_index);
local pos = flib_position.to_tile(player.position);
local surface = game.surfaces.nauvis;
local moistMeter = surface.calculate_tile_properties({
"elevation", "temperature", "moisture"
}, {
pos
});
Gen_Soil_Data(moistMeter);
local oneD = get_point(pos);
if myData[oneD] ~= nil then
local test = game.get_filtered_entity_prototypes({
{
filter = "name",
name = "tree-01"
}
});
end;
end);
script.on_event(defines.events.on_chunk_generated, function(event)
local myData = global.myData;
local test = event.surface.find_tiles_filtered({
area = event.area,
name = {
"grass-1",
"grass-2",
"grass-3",
"grass-4"
}
});
local newTiles = {};
for _, x in ipairs(test) do
global.myData[get_point(x.position)] = {
test = 32
};
end;
end);
script.on_event(defines.events.on_resource_depleted, function(event)
if event.entity.name == "pre_soil_ore" then
local surface = game.surfaces.nauvis;
local pos = event.entity.position;
surface.set_tiles({
tiles = {
name = "soil",
position = pos,
radius = 1
}
});
end;
end);
script.on_event(defines.events.on_script_trigger_effect, function(event)
local callBack = registeredEntityCallbacks[event.target_entity.name];
local source_entity = event.source_entity;
if event.effect_id == "pretill-spawned" then
game.print("date");
end;
if callBack ~= nil then
local initObject = exchange[source_entity.name] or {};
local init = callBack.init(source_entity, initObject);
if callBack.iterate ~= nil then
global.registeredEntities[source_entity] = {
entity = source_entity,
state = init
};
end;
end;
end);
script.on_nth_tick(5, function()
local surface = game.surfaces.nauvis;
for entity, registered in pairs(global.registeredEntities) do
if entity.valid then
local resultObj = registeredEntityCallbacks[entity.name].iterate(surface, registered);
local endLife = resultObj.end_life;
local replace = resultObj.replace;
if endLife and replace == nil then
global.registeredEntities[entity] = nil;
elseif replace ~= nil then
Replace_entity(replace, surface, registered);
global.registeredEntities[entity] = nil;
end;
else
game.print(registered.state.our_value);
global.registeredEntities[entity] = nil;
end;
end;
end);