Mining drill for trees
Mining drill for trees
Is it possible to create a building that automatically harvests any tree around it? Like a mining drill except it affects a much larger area, removes trees within the affected area and outputs raw wood?
And before anyone says "just use bots" I'm picturing something early game that could be used as an early source of fuel before you have access to bots.
And before anyone says "just use bots" I'm picturing something early game that could be used as an early source of fuel before you have access to bots.
Re: Mining drill for trees
May be raw wood ore? Something like stone ore, that can be mined from stones or from fields.
- eradicator
- Smart Inserter
- Posts: 5207
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Mining drill for trees
Anything's possible with scripts (:
- Cache a list of trees around the building in on_built
- Sort list by distance of each tree
- Every few ticks catch the first (closest) tree from the list, kill it and put the wood into the machine
Re: Mining drill for trees
How to place the mining drill without ore patch?eradicator wrote:Anything's possible with scripts (:
- Cache a list of trees around the building in on_built
- Sort list by distance of each tree
- Every few ticks catch the first (closest) tree from the list, kill it and put the wood into the machine
Energy consumption?
- eradicator
- Smart Inserter
- Posts: 5207
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Mining drill for trees
assembling-machinedarkfrei wrote:How to place the mining drill without ore patch?
In step 3) substract energy from the assembling-machines energy buffer.darkfrei wrote:Energy consumption?
Re: Mining drill for trees
Even if you said no bots, I say use bots.
Make the mining entity a roboport with an logistics area covering less than it's base so they don't connect.
Give it a hidden logistic chest as output and a hidden unkillable bot to mine.
Make a script that marks trees in the construction area for deconstruction when the entity is placed.
This should be a lot more lightweight on ups than a script running every n ticks removing trees and adding the wood.
Make the mining entity a roboport with an logistics area covering less than it's base so they don't connect.
Give it a hidden logistic chest as output and a hidden unkillable bot to mine.
Make a script that marks trees in the construction area for deconstruction when the entity is placed.
This should be a lot more lightweight on ups than a script running every n ticks removing trees and adding the wood.
My Mods: mods.factorio.com
- eradicator
- Smart Inserter
- Posts: 5207
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Mining drill for trees
Treefarm-lite (from 0.13 times?) used robots to farm trees. It was horrible. With just one bot and one construction order it might be less bad but there's still problems with that:
- You have a roboport with robot-docking-capability that will connect to your future robot network. Possible fix: Use a bot that requires no energy and remove the docking port.
- And you use up part of the robot-task-queue. Possible fix don't mark all the trees at once, but then you're back to on_tick.
- And you use a logistic chest that will connect to any other logistic network that happens to cover it when a normal roboport is "too close". Possible fix: Put it on a different force, and voila you're back to on_tick again.
- Oh, and if your wood-chopping-robot-port loses power the hidden robot might migrate into your main network. Possible fix: on_tick check for lost robots.
Re: Mining drill for trees
All your points are valid if you use it in conjucture with roboports.
However the op explicitly wanted something for pre-roboport game so none of them matter.
By the time roboports become available this whole tree miner entity becomes obsoleted by vanilla roboports anyway regardless of implementation.
However the op explicitly wanted something for pre-roboport game so none of them matter.
By the time roboports become available this whole tree miner entity becomes obsoleted by vanilla roboports anyway regardless of implementation.
My Mods: mods.factorio.com
- eradicator
- Smart Inserter
- Posts: 5207
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Mining drill for trees
Doesn't matter. 1) and 4) will still mess with your network even if the entity already chopped up all trees. And you can't guarantee that the player will remove all wood-choppers before placing their first roboport.Optera wrote:All your points are valid if you use it in conjucture with roboports.
However the op explicitly wanted something for pre-roboport game so none of them matter.
Re: Mining drill for trees
1) i explicitly wrote "make the logistic area smaller than entity size" that way it can never connect to another miner
4) set power consumption for the hidden bot to 0 if you're worried about that
4) set power consumption for the hidden bot to 0 if you're worried about that
My Mods: mods.factorio.com
Re: Mining drill for trees
Thanks, this seems like a workable way to do it. Since trees never grow back you can just check if the tree is still valid and skip to the next if it's been deleted, then disable the building when the list is empty.eradicator wrote:Anything's possible with scripts (:
- Cache a list of trees around the building in on_built
- Sort list by distance of each tree
- Every few ticks catch the first (closest) tree from the list, kill it and put the wood into the machine
Now to figure out how to actually code it as a complete newbie to Factorio modding.
- eradicator
- Smart Inserter
- Posts: 5207
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Mining drill for trees
I was bored and wrote a simple control.lua only demonstration. It makes wooden chests slowly chop up trees around themselfs (one every 5 seconds configurable). It doesn't do any caching at all. It also doesn't do circles because that would require fetching all trees around each, instead of just one. I.e. it would be more expensive, though probably still insignificantly.
Pros:
License: MIT (included in zip file)
Download: @OP: If you're new to factorio be advised that i use a self-deactivating on_tick handler here, if done wrong this can quickly cause desyncs in multiplayer (which is also untested so it might already :p). So if you want to modify it's better to switch back to a static handler and accept the slight overhead that causes.
Pros:
- Zero impact on savegame size when all trees in range have been chopped.
- Zero impact on on_tick once all trees have been chopped.
- Can be quickly changed to use a different entity.
- Script impact <0.01ms while active (unless you really spam them)
- Less than 60 lines of code.
- Type/Range/Interval configurable in file header
- Uses new and shiny on_nth_tick
- It's called "Beavers!" :p.
- Won't work with mods that spawn in new trees (unless they spawn them fast enough).
- Doesn't support energy consumption yet, though that's trivial to add.
- Due to usage of on_nth_tick requires care when integrating into existing codebase.
- All entities updated at once, makes it look less natural.
Code: Select all
--VERSION 0.0.1
--makes all entities of type beaver_species slowly collect trees around themselfs
local beaver_species = 'wooden-chest' --this entity is a beaver (needs an inventory)
local beaver_max_range = 24 --in tiles
local beaver_interval = 5*60 --in ticks
local function unleash_the_beavers(e)
-- feeds each beaver one tree per interval
-- print('There are ' .. #global.beavers .. ' beavers alive.')
for b,beaver in pairs(global.beavers) do
if not beaver.specimen.valid then
table.remove(global.beavers,b)
else
local territory = {
{beaver.specimen.position.x-beaver.range,beaver.specimen.position.y-beaver.range},
{beaver.specimen.position.x+beaver.range,beaver.specimen.position.y+beaver.range}}
local tree = beaver.specimen.surface.find_entities_filtered{type='tree',limit=1,area=territory}[1]
if not tree then
if beaver.range >= beaver_max_range then
table.remove(global.beavers,b)
else
beaver.range = beaver.range + 1
end
else
--can trees actually have more than one type of product?
local twigs = tree.prototype.mineable_properties.products
local eaten = 0
for _,twig in pairs(twigs) do
beaver.specimen.insert{name=twig.name,count=twig.amount}
eaten = eaten + 1
end
--tree dies only if all twigs fit into the beaver
--this coult be exploited to gain infinite resources from a single tree
if #twigs == eaten then tree.die() end
end
end
end
if #global.beavers == 0 then
--no more active beavers, get rid of the handler
global.beavers = nil
script.on_nth_tick(beaver_interval,nil)
end
end
local function prepare_the_beavers()
if global.beavers then
script.on_nth_tick(beaver_interval,unleash_the_beavers)
end
end
script.on_load(prepare_the_beavers)
script.on_init(prepare_the_beavers)
script.on_configuration_changed(prepare_the_beavers)
script.on_event(
{defines.events.on_built_entity,
defines.events.on_robot_built_entity},
function(e)
if not e.created_entity.name == beaver_species then return end
-- print('I saw a beaver!')
if not global.beavers then global.beavers = {} end
global.beavers[#global.beavers+1] = {specimen = e.created_entity, range = 5}
prepare_the_beavers()
end)
Download: @OP: If you're new to factorio be advised that i use a self-deactivating on_tick handler here, if done wrong this can quickly cause desyncs in multiplayer (which is also untested so it might already :p). So if you want to modify it's better to switch back to a static handler and accept the slight overhead that causes.
Re: Mining drill for trees
neat @era
Re: Mining drill for trees
That code is a great help, thanks!eradicator wrote:I was bored and wrote a simple control.lua only demonstration. It makes wooden chests slowly chop up trees around themselfs (one every 5 seconds configurable). It doesn't do any caching at all. It also doesn't do circles because that would require fetching all trees around each, instead of just one. I.e. it would be more expensive, though probably still insignificantly.
I was already hacking away at something, but my thinking had me use an assembler with a fixed recipe that created wood, and before starting each cycle would check if there was a tree within range and if so it would destroy that tree.
I then realized that a) not all trees are created equal, some give more wood than others, and b) there doesn't seem to be an event for when an assembler starts its cycle, so I'd have to check every tick if it was at the start of its cycle.
I think your solution is much more elegant.
edit: Tried installing your beavers and every building spawns beavers now.
This function doesn't behave as expected and never returns from the function. I can't see what's wrong with it though. I added some debugging and the strings are clearly not identical yet it's not caught by the if not clause.
Code: Select all
if not e.created_entity.name == beaver_species then return end
Re: Mining drill for trees
I found another bug, the check to see if inventory is full doesn't work. I replaced that code with a call to can_insert() instead.
I've added an entity for a harvesting machine, extended from the container type. Is it possible to make a container require power? And is it possible to animate it and start/stop the animation from code? Or would I be better off extending another type?
I've added an entity for a harvesting machine, extended from the container type. Is it possible to make a container require power? And is it possible to animate it and start/stop the animation from code? Or would I be better off extending another type?
- eradicator
- Smart Inserter
- Posts: 5207
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Mining drill for trees
It's doing boolean comparison, which always ends in "if true == false". Adding brackets works, as does inequality:
(Though i can think of some more ugly hacks, like sneakily spawning wood ore, because miners can multi-result...but then you need a seperate ore for every. possible. drop)
Code: Select all
if not (e.created_entity.name == beaver_species) then return end
if e.created_entity.name ~= beaver_species then return end
Define "doesn't work". I didn't use can_insert() because that can't check multiple items at once. And a mod can add additional results, like a tree that drops wood and seeds. Also i just noticed that the drop-getting logic doesn't handle probability.mg79 wrote:I found another bug, the check to see if inventory is full doesn't work. I replaced that code with a call to can_insert() instead.
prototype of rock-huge wrote:Code: Select all
results = {{name = "stone", amount_min = 24, amount_max = 50}, {name = "coal", amount_min = 24, amount_max = 50}},
Nope, containers can't consume energy or be animated. The original idea was to use an assembler and shove the stuff into the output slot. But with the possibility of multiple results...meh. Electric-energy-interface can animate and consume energy (or just supply a buffer). But then you'd need to do a complex entity because it doesn't have an inventory. An assembler with a recipe that turns 1 wood into 1 wood (just to animate)...would have worked, except meh multiple drops. EEI+container looks like the best way if you really want animation.mg79 wrote:I've added an entity for a harvesting machine, extended from the container type. Is it possible to make a container require power? And is it possible to animate it and start/stop the animation from code? Or would I be better off extending another type?
(Though i can think of some more ugly hacks, like sneakily spawning wood ore, because miners can multi-result...but then you need a seperate ore for every. possible. drop)
Re: Mining drill for trees
It would keep killing trees even if its inventory was full. I don't know if maybe the insert() calls always succeeds even if the inventory was full.eradicator wrote:It's doing boolean comparison, which always ends in "if true == false". Adding brackets works, as does inequality:
Define "doesn't work". I didn't use can_insert() because that can't check multiple items at once. And a mod can add additional results, like a tree that drops wood and seeds. Also i just noticed that the drop-getting logic doesn't handle probability.prototype of rock-huge wrote:Code: Select all
results = {{name = "stone", amount_min = 24, amount_max = 50}, {name = "coal", amount_min = 24, amount_max = 50}},
But yeah, multiple drops are a pain in the butt. It would be nice if there was a "generic-machine" type that extended CraftingMachine that was more flexible than the assembling-machine type and could have animation and stuff controlled from lua.
I think for now a wood->wood recipe is the least bad way to do it.
Re: Mining drill for trees
Ok I got it the way I want it now, through a kludge.
I added a new "Timber" item. If the tree has raw wood, the assembler will add the same amount of timber and destroy the tree, but only if there's less than 5 units of timber in the machine already. It then has a fixed recipe that makes 1 raw wood from 1 timber and takes 1 second. This has the advantage that stumps and dead trees which normally only give 2 wood will also harvest faster. Now harvesting speed is dependent on the machine's crafting speed, so if you're low on power you'll also harvest slower. You could still cheat by taking the timber out of the machine's input to get it to harvest faster, but you still need to process the timber into wood anyway, and you can't just steal raw wood from the input.
The mod doesn't support multiple products from trees. It will simply ignore anything that isn't raw wood, so if you're using arborium or some other mod that adds seeds/saplings you have to harvest them manually.
Give it a try.
e: One thing that is still missing is having the building show how big the affected area is during placement. I don't know if it's possible to do that on an assembling-machine?
e2: New version, tiny bugfixes like the recipe not having stupid requirements any more. I still can't get it to sort properly in the crafting list, no matter what I try it places itself after the assembling machine 1...
I added a new "Timber" item. If the tree has raw wood, the assembler will add the same amount of timber and destroy the tree, but only if there's less than 5 units of timber in the machine already. It then has a fixed recipe that makes 1 raw wood from 1 timber and takes 1 second. This has the advantage that stumps and dead trees which normally only give 2 wood will also harvest faster. Now harvesting speed is dependent on the machine's crafting speed, so if you're low on power you'll also harvest slower. You could still cheat by taking the timber out of the machine's input to get it to harvest faster, but you still need to process the timber into wood anyway, and you can't just steal raw wood from the input.
The mod doesn't support multiple products from trees. It will simply ignore anything that isn't raw wood, so if you're using arborium or some other mod that adds seeds/saplings you have to harvest them manually.
Give it a try.
e: One thing that is still missing is having the building show how big the affected area is during placement. I don't know if it's possible to do that on an assembling-machine?
e2: New version, tiny bugfixes like the recipe not having stupid requirements any more. I still can't get it to sort properly in the crafting list, no matter what I try it places itself after the assembling machine 1...
Last edited by mg79 on Sun Jul 08, 2018 4:05 pm, edited 2 times in total.
- eradicator
- Smart Inserter
- Posts: 5207
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Mining drill for trees
Huh, i was sure they only run when the version changes :D. So many pitfalls...Factorio API wrote:When adding a mod to an existing save all migration scripts for that mod will be run.
Also there's a built-in module called "util" so you might want to use a different name in the future to avoid confusion.
Hm..also removed the "harvest closest trees first". The only beauty function i added to the original, because i thought it looked/felt really meh if it starts in some far away corner. Especially if the player is trying to see if it works and doesn't see the far-away trees vanishing.
Well. If you look very very closely... you'll notice that there's no actual check if insert() succeeded or not. I simply forgot that ;). Should check for return value of 0 i guess.mg79 wrote: It would keep killing trees even if its inventory was full. I don't know if maybe the insert() calls always succeeds even if the inventory was full.
Showing an overlay for arbitrary entities... is a (one?two?...) pending interface request that's getting buried deeper every day. Plase bump if you manage to find it :)
The order string should probably be something like "a[items]-b[wood-harvester]" or "a[items]-b[electric-mining-drill]a". Order strings are just strings. Don't get distracted by the dashes and brackets, they have no special meaning.
:sadface: Maybe you can drop them on the ground. surface.create_entity{name="item-on-ground",...}. Or spawn a chest alongside the harvester to collect them.mg79 wrote:The mod doesn't support multiple products from trees.
Anyways, congratulations on your first mod.
(Something around here smells like dead beaver ;)