
help with making a harvester
Re: help with making a harvester
Ok thanks for the fast reply. 

Re: help with making a harvester
Hey I'm working on the "refinery" building its like a really big storage chest, and I have ran into a problem. The image I'm using is rather large to match the scale of the harvester (216 x 216) and the inserters are taking longer to mover items back and forth then normal because the inserters are reaching to the center of the image and stretching. Is there any way to make the inserters reach in a normal way or no? Maybe increasing inserter's extension speed when it is taking from the refinery?
Re: help with making a harvester
they are 'bound' to the collision box, so you could change the collision box of the refinery but that's the only way I really know of...McSpiffy wrote:Is there any way to make the inserters reach in a normal way or no?
...of course you could have the control.lua transfer the ore when you are close to a refinery (as if you were 'dumping' the ore into it), rather than using inserters.
Re: help with making a harvester
FreeER wrote:...of course you could have the control.lua transfer the ore when you are close to a refinery (as if you were 'dumping' the ore into it), rather than using inserters.
Yea that was the plan its just I wanted to make taking the ore out of the refinery faster.
Maybe something like if inserter is next to refinery change inserter speed to #
Re: help with making a harvester
oh, right that makes sense tooMcSpiffy wrote:I wanted to make taking the ore out of the refinery faster.

I'm not sure that you can change the speed of inserters through lua though...I'll assume you've tested with the fast inserters and not just the basic ones...trying to think of something that doesn't involve creating faster inserters and replacing nearby inserters with them (since that could cause issues)....hm... other than checking the nearby inserters' 'heldstack' and increasing it's count by a factor of 4 or so (and decrementing the refinery's) if it is holding something that is in the refinery (and even that could have issues depending on if other unrelated inserters are nearby), I'm not sure of a decent way to make it faster.
Re: help with making a harvester
lol ok i guess i'll mess around with it and see
Re: help with making a harvester
See this is the problem the inserters over extend and the take more time to retract.
- Attachments
-
- 2014-05-13 21_56_47-Greenshot.jpg (316.85 KiB) Viewed 4901 times
Re: help with making a harvester
yeah, the same happens (at least it used to) in the treefarm mod...I was thinking they reached to the center of the collision box but from the image it looks like they actually reach for the center of the sprite...
hm...not certain it would work but maybe you could have a regular chest (or an invisible one) spawn with the placement of a refinery and use that for the inventory instead, though it might make some of the code a bit more complicated and would probably detract from the 'refinery' aspect a bit...another option might be to make it output items on it's own (using game.createentity{name="item-on-ground", position={refinery.position.x+5, refinery.position.y-7}, stack={name="ore-from-inventory", count=x} and game.canplaceentity, the 5 and 7 were just random numbers...x is of course how much to remove each time) so it acts similar to a mining drill (actually...I kind of wonder if you could use a mining drill with a larger inventory and have it do that for you whenever items are inserted...I'm not sure).
hm...not certain it would work but maybe you could have a regular chest (or an invisible one) spawn with the placement of a refinery and use that for the inventory instead, though it might make some of the code a bit more complicated and would probably detract from the 'refinery' aspect a bit...another option might be to make it output items on it's own (using game.createentity{name="item-on-ground", position={refinery.position.x+5, refinery.position.y-7}, stack={name="ore-from-inventory", count=x} and game.canplaceentity, the 5 and 7 were just random numbers...x is of course how much to remove each time) so it acts similar to a mining drill (actually...I kind of wonder if you could use a mining drill with a larger inventory and have it do that for you whenever items are inserted...I'm not sure).
Re: help with making a harvester
OK i'll look into it tomorrow. Thanks again for the advice!
Re: help with making a harvester
Hey so I've been looking at making the refinery into a mining-drill entity and was wondering if I could disable the "resource_categories" in order to place it anywhere or maybe the "mining_power"
I was messing with it, and if i set the mining_power to 0.5 it can only be placed on stone if it is 3 it can be place on stone,coal,iron, and copper. Is there anyway of getting around this? Also can i make it so the inventory is visible?
So I can start seeing if it can draw from the inventory instead of mining. >.<
Or hell even making it spawn store ore under it when placing would be fine, or tricking it to think that ore is everywhere.
I was messing with it, and if i set the mining_power to 0.5 it can only be placed on stone if it is 3 it can be place on stone,coal,iron, and copper. Is there anyway of getting around this? Also can i make it so the inventory is visible?
So I can start seeing if it can draw from the inventory instead of mining. >.<
Or hell even making it spawn store ore under it when placing would be fine, or tricking it to think that ore is everywhere.
Re: help with making a harvester
hm...forgot about that little 'feature' of the mining drill 
the onputitem event would let you know when someone tries to place the harvester, you could then use game.createentity to either spawn ore there (since onputitem is called before onentitybuilt) or to place the harvester directly (game.createentity does little, if any, checks for valid placement)
as for the inventory...hm I didn't realize it was hidden...well that makes it pretty much useless...(I don't believe inserters would even put into a drill anything but fuel...)
Well...sorry for wasting your time with that idea
though you should be able to approximate it with code if you wanted (check every second or so if the refinery has items in it's inventory if so remove x amount and create an item entity with a stack of that name and x amount at a position relative to the refinery's position).

the onputitem event would let you know when someone tries to place the harvester, you could then use game.createentity to either spawn ore there (since onputitem is called before onentitybuilt) or to place the harvester directly (game.createentity does little, if any, checks for valid placement)
as for the inventory...hm I didn't realize it was hidden...well that makes it pretty much useless...(I don't believe inserters would even put into a drill anything but fuel...)
Well...sorry for wasting your time with that idea

Re: help with making a harvester
ok well I will see what I can do when I get back (need to head to the doctor's office >.<)
Re: help with making a harvester
so I guess I'm not on the right track >.>
Code: Select all
game.onevent(defines.events.onputitem, function(event)
if event.onputitem.name == "refinery" then
game.createentity{name = "stone",}
end
end)
Re: help with making a harvester
Well, for one thing createentity requires the position at which to create the entity, something like
Code: Select all
game.createentity{name="stone", position=event.position}
Re: help with making a harvester
ok I will try this do you have any pointers or guide lines I should follow to attempt this. I'm starting to feel like I'm not very good at thisFreeER wrote: Well...sorry for wasting your time with that ideathough you should be able to approximate it with code if you wanted (check every second or so if the refinery has items in it's inventory if so remove x amount and create an item entity with a stack of that name and x amount at a position relative to the refinery's position).

Update: I tried my hand at some of it and this is what I came up with.
Code: Select all
game.onevent(defines.events.ontick, function()
if game.tick % 60 == 0 then
if game.container.name == "refinery" then
local storageItem = game.container.getinventory(1)
local itemAmount = 7 -- stack size
if item.name > 0 then
game.container.remove{name = item.name, count = itemAmount}
game.createentity{name = name= "storageItem", position = {game.container.name == "refinery", 2}, count = itemAmount}
end
end
end
end)
Re: help with making a harvester
Don't worry, it takes a bit of time to really understand it but after you do you'll be fine (obviously...McSpiffy wrote:I'm starting to feel like I'm not very good at this

I think you'd use something along these lines (it's a bit late so if it doesn't work there's probably a bug...sorry). If you load a save you'll need to mine and replace the refineries for the code to actually detect them.
Code: Select all
game.oninit(function() --create refineries table on new game
if not glob.refineries then glob.refineries = {} end
end)
game.onload(function()
--create refineries table on load (if it does not exist)
if not glob.refineries then glob.refineries = {} end
end)
game.onevent(defines.events.onbuiltentity, function(event)
if event.createdentity.name = "refinery" then
table.insert(glob.refineries, event.createdentity)
end
end)
game.onevent(defines.events.ontick, function()
if game.tick % 60 == 0 then
for index, refinery in ipairs(glob.refineries) do
if refinery.valid then
if refinery.getitemcount() > 0 then -- if the refinery has items
-- the inventory number may be wrong... the [1] selects
-- the first item stack in the inventory
local item = refinery.getinventory(1)[1]
local itemAmount = 7 -- stack size
-- make item.count reflect the amount we are inserting/removing
-- only checking for > because we don't want to insert more if
-- if there are actually less than itemAmount in the refinery
if item.count > itemAmount then item.count = itemAmount end
-- you'll probably need to play with these number to get it to
-- place where you want it to...
-- there is also refinery.direction which tells you whether
-- the refinery is pointing north, south etc. so if you get
-- ambitious you can try to make it place the output to the
-- same relative side rather than always in one direction...
local storagePos = {refinery.position.x + 5, refinery.position.y + 5}
-- get any entities at that storagePosition
local storageEntities = game.findentities(storagePos)
local storageEntity = false -- temp bool
for _, entity in ipairs(storageEntities) do
if entity.caninsert(item) then
storageEntity = entity -- save a reference to this entity
break -- and break out of the loop
end
end
if storageEntity then -- if an entity that we can place the item into was found
storageEntity.insert(item)
refinery.remove(item)
-- no entities at all (just an else statement would allow dropping them even if there was, say, a wall there
elseif storageEntities == nil then
-- just place the item on the ground
game.createentity{name="item-on-ground", position=storagePos, stack=item}
refinery.remove(item)
end
end
else -- not a valid refinery anymore
table.remove(glob.refineries, index) -- remove from table
end
end
end
end)
Re: help with making a harvester
Ok I'v been trying to use what you suggested but i got and error for this line
the error is: bad argument #-1 to 'findentities'(table expected, got number)
Code: Select all
local storageEntities = game.findentities(storagePos)
Re: help with making a harvester
oh oops, can't believe I forgot that...
findentities requires the bounding box of the area to search (and storagePos is just one point).
... theres probably a bug in onbuiltentity (name = "refinery" instead of name == "refinery")
... looking at this again there might be a bug with the item = code (now that I think about it the items probably are not sorted in the refinery like they would typically be in the player's inventory...). If that is the case then this should take care of that
again, sorry 
Code: Select all
local storageEntities = game.findentities(getBoundingBox(storagePos, 1))
... theres probably a bug in onbuiltentity (name = "refinery" instead of name == "refinery")
... looking at this again there might be a bug with the item = code (now that I think about it the items probably are not sorted in the refinery like they would typically be in the player's inventory...). If that is the case then this should take care of that
Code: Select all
local item
for _, slot in pairs(refinery.getinventory(1)) do -- find the first slot with an item instead of assuming the first slot
if slot then -- if the inventory slot has something in it
item = slot -- set item to hold the same item stack
break
end
end

Re: help with making a harvester
So I'm have problems when i put the harvester script and the refinery scrip in the same control lua. I think It has something to do with the getBoundingBox
This is what I have
This is what I have
Code: Select all
require "defines" -- has a bunch of defined constants for events and inventory, etc. the file itself is data\core\lualib\defines.lua
--// Harvester //--
game.onevent(defines.events.ontick, function() --tell game we want to do stuff every tick (60 times per second)
if game.tick % 60 == 0 then -- do this only once per second, you can decrease 60 if needed...but it'd probably be better to increase the amount of ore being removed
if game.player.vehicle and game.player.vehicle.name == "harvester" then -- if the player is in a vehicle and it is a harvester
local ore = game.findentitiesfiltered{type = "resource", area=getBoundingBox(game.player.vehicle.position, 2)} -- get a table of the ore within a (square) radius of 10 around the harvester, thankfully that was fairly easy, change the '10' to any value you think is appropriate, the 'type = "resource"' might allow it to 'mine' trees as well...if so and you didn't want that you'd need to have multiple tables and instead search using 'name = "name_of_ores"'
local oreAmount = 1 -- amount of ore to mine from each resource spot
for _, ore in ipairs(ore) do -- loop through those ores
if ore.name ~= "crude-oil" and ore.name:sub(-4) ~= "tree" then
if game.player.vehicle.caninsert{name = ore.name, count = oreAmount} then -- if the harvester is not full
if ore.amount >= oreAmount then -- if there is more than enough ore
ore.amount = ore.amount - oreAmount -- decrement the ore by oreAmount
game.player.vehicle.insert{name = ore.name, count = oreAmount} -- and insert it into the harvester
else -- if the amount of ore left is not greater than or equal to what we want to remove, just remove all of it (without the else, it'd leave any spots less than oreAmount...which would be somewhat annoying lol)
game.player.vehicle.insert{name = ore.name, count = ore.amount} -- insert first so that we don't need a local variable to store the amount
ore.amount = 0 -- then just set ore amount to 0 instead doing ore.amount = ore.amount - ore.amount (cause that looks silly :))
end
end
end
end
end
--auto coal placement into burner from trunk
if game.player.vehicle and game.player.vehicle.name == "harvester" then
local burnerCoal = game.player.vehicle.getinventory(1)
local trunkCoal = game.player.vehicle.getinventory(2)
-- notice that I combined these since you won't do anything if only one is true
if burnerCoal.getitemcount() <= 19 and trunkCoal.getitemcount("coal") > 0 then
trunkCoal.remove({name="coal", count="1"})
burnerCoal.insert({name="coal", count="1"})
end
end
end
end) -- end anonymous function and onevent/ontick call5
function getBoundingBox(position, radius)
return {{position.x - radius, position.y-radius}, {position.x + radius, position.y + radius}}
end
--// Refinery //--
game.oninit(function() --create refineries table on new game
if not glob.refineries then glob.refineries = {} end
end)
game.onload(function()
--create refineries table on load (if it does not exist)
if not glob.refineries then glob.refineries = {} end
end)
game.onevent(defines.events.onbuiltentity, function(event)
if event.createdentity.name == "refinery" then
table.insert(glob.refineries, event.createdentity)
end
end)
game.onevent(defines.events.ontick, function()
if game.tick % 60 == 0 then
for index, refinery in ipairs(glob.refineries) do
if refinery.valid then
if refinery.getitemcount() > 0 then -- if the refinery has items
-- the inventory number may be wrong... the [1] selects
-- the first item stack in the inventory
local item = refinery.getinventory(1)[1]
local itemAmount = 1 -- stack size
-- make item.count reflect the amount we are inserting/removing
-- only checking for > because we don't want to insert more if
-- if there are actually less than itemAmount in the refinery
if item.count > itemAmount then item.count = itemAmount end
-- you'll probably need to play with these number to get it to
-- place where you want it to...
-- there is also refinery.direction which tells you whether
-- the refinery is pointing north, south etc. so if you get
-- ambitious you can try to make it place the output to the
-- same relative side rather than always in one direction...
local storagePos = {refinery.position.x + 0, refinery.position.y + 5 }
-- get any entities at that storagePosition
local storageEntities = game.findentities(getBoundingBox(storagePos, 1))
local storageEntity = false -- temp bool
for _, entity in ipairs(storageEntities) do
if entity.caninsert(item) then
storageEntity = entity -- save a reference to this entity
break -- and break out of the loop
end
end
if storageEntity then -- if an entity that we can place the item into was found
storageEntity.insert(item)
refinery.remove(item)
-- no entities at all (just an else statement would allow dropping them even if there was, say, a wall there
elseif storageEntities == nil then
-- just place the item on the ground
game.createentity{name="item-on-ground", position=storagePos, stack=item}
refinery.remove(item)
end
end
else -- not a valid refinery anymore
table.remove(glob.refineries, index) -- remove from table
end
end
end
end)
Re: help with making a harvester
ok..there were a couple of little bugs, should be fixed now and you'll just need to play with the storage position (line 87). I suppose I should note that I used a wooden-chest for testing (since I haven't yet updated to the newest version of your mod
)...but it should be fine, I hope...

Code: Select all
require "defines" -- has a bunch of defined constants for events and inventory, etc. the file itself is data\core\lualib\defines.lua
game.oninit(function() --create refineries table on new game
if not glob.refineries then glob.refineries = {} end
end)
game.onload(function()
--create refineries table on load (if it does not exist)
if not glob.refineries then glob.refineries = {} end
end)
-- store each built refinery in the glob.refineries table
game.onevent(defines.events.onbuiltentity, function(event)
if event.createdentity.name == "refinery" then
table.insert(glob.refineries, event.createdentity)
end
end)
--// Harvester //--
game.onevent(defines.events.ontick, function() --tell game we want to do stuff every tick (60 times per second)
if game.tick % 60 == 0 then -- do this only once per second, you can decrease 60 if needed...but it'd probably be better to increase the amount of ore being removed
if game.player.vehicle and game.player.vehicle.name == "harvester" then -- if the player is in a vehicle and it is a harvester
local ore = game.findentitiesfiltered{type = "resource", area=getBoundingBox(game.player.vehicle.position, 2)} -- get a table of the ore within a (square) radius of 10 around the harvester, thankfully that was fairly easy, change the '10' to any value you think is appropriate, the 'type = "resource"' might allow it to 'mine' trees as well...if so and you didn't want that you'd need to have multiple tables and instead search using 'name = "name_of_ores"'
local oreAmount = 7 -- amount of ore to mine from each resource spot
for _, ore in ipairs(ore) do -- loop through those ores
if ore.name ~= "crude-oil" and ore.name:sub(-4) ~= "tree" then
if game.player.vehicle.caninsert{name = ore.name, count = oreAmount} then -- if the harvester is not full
if ore.amount >= oreAmount then -- if there is more than enough ore
ore.amount = ore.amount - oreAmount -- decrement the ore by oreAmount
game.player.vehicle.insert{name = ore.name, count = oreAmount} -- and insert it into the harvester
else -- if the amount of ore left is not greater than or equal to what we want to remove, just remove all of it (without the else, it'd leave any spots less than oreAmount...which would be somewhat annoying lol)
game.player.vehicle.insert{name = ore.name, count = ore.amount} -- insert first so that we don't need a local variable to store the amount
ore.amount = 0 -- then just set ore amount to 0 instead doing ore.amount = ore.amount - ore.amount (cause that looks silly :))
end
end
end
end
end
--auto coal placement into burner from trunk
if game.player.vehicle and game.player.vehicle.name == "harvester" then
local burnerCoal = game.player.vehicle.getinventory(1)
local trunkCoal = game.player.vehicle.getinventory(2)
-- notice that I combined these since you won't do anything if only one is true
if burnerCoal.getitemcount() <= 19 and trunkCoal.getitemcount("coal") > 0 then
trunkCoal.remove({name="coal", count="1"})
burnerCoal.insert({name="coal", count="1"})
end
end
-- start of refinery code
for index, refinery in ipairs(glob.refineries) do
if refinery.valid then
if refinery.getitemcount() > 0 then -- if the refinery has items
-- the inventory number may be wrong... the [1] selects
-- the first item stack in the inventory
local item
-- bit of a 'hack' here...
-- the bug did occur where just selecting the first inventory
-- would be nil fairly quickly...but the for loop I posted
-- on the forums didn't work because the slot is 'userdata'
-- and you can not index userdata...
-- so I use getcontents() which returns a regular lua table
-- but it returns it indexed by the item name...and that's
-- one of the pieces of info that we actually need to get back
-- soo here's a for loop that simply selects whatever lua gives
-- back first (since associative arrays have no guarenteed order)
-- and uses that as the 'first' item
for name, count in pairs(refinery.getinventory(defines.inventory.chest).getcontents()) do
item = {name=name, count=count}
break
end
local itemAmount = 7 -- stack size
-- make item.count reflect the amount we are inserting/removing
-- only checking for > because we don't want to insert more if
-- if there are actually less than itemAmount in the refinery
if item.count > itemAmount then item.count = itemAmount end
-- you'll probably need to play with these number to get it to
-- place where you want it to...
-- there is also refinery.direction which tells you whether
-- the refinery is pointing north, south etc. so if you get
-- ambitious you can try to make it place the output to the
-- same relative side rather than always in one direction...
local storagePos = {x = refinery.position.x + 0, y = refinery.position.y + 5 }
-- get any entities at that storagePosition
local storageEntities = game.findentities(getBoundingBox(storagePos, 1))
local storageEntity = false -- temp bool
for _, entity in ipairs(storageEntities) do
if entity.caninsert(item) then
storageEntity = entity -- save a reference to this entity
break -- and break out of the loop
end
end
if storageEntity then -- if an entity that we can place the item into was found
storageEntity.insert(item)
refinery.getinventory(defines.inventory.chest).remove(item)
-- no entities at all (just an else statement would allow dropping them even if there was, say, a wall there
elseif #storageEntities == 0 then
-- just place the item on the ground
game.createentity{name="item-on-ground", position=storagePos, stack=item}
refinery.getinventory(defines.inventory.chest).remove(item)
end
end
else -- not a valid refinery anymore
table.remove(glob.refineries, index) -- remove from table
end
end -- end of refinery code
end -- end of ontick%60
end) -- end anonymous function and onevent/ontick calls
function getBoundingBox(position, radius)
return {{position.x - radius, position.y - radius}, {position.x + radius, position.y + radius}}
end