Code: Select all
for k, v in pairs( data.raw.tree ) do
if not string.match(v.name, "dead") then
v.healing_per_tick = .01
end
end
Code: Select all
for k, v in pairs( data.raw.tree ) do
if not string.match(v.name, "dead") then
v.healing_per_tick = .01
end
end
Not so simple it turns outTaehl wrote:an excellent, simple idea for a mod
Code: Select all
require "defines"
game.oninit(function() -- ran when the mod is first loaded
glob.trees = {}
glob.trees.start = 1
glob.trees.health = {}
end)
game.onload(function() -- ran when a game is loaded (needed for already started games)
-- essentially the same as oninit... so... code duplication alert :)
if not glob.trees then
glob.trees = {}
glob.trees.start = 1
glob.trees.health = {}
end
end)
game.onevent(defines.events.onchunkgenerated, function(event)
local trees = game.findentitiesfiltered{type="tree", area=event.area}
-- remove "dead" trees, loop backwards since we're deleting items
for index=#trees, 1, -1 do
local tree = trees[index]
if tree.name:match('dead') then
table.remove(trees, index)
else
if not glob.trees.health[tree.name] then
glob.trees.health[tree.name] = game.entityprototypes[tree.name].maxhealth
end
end
end
table.insert(glob.trees, trees) -- insert adjusted area table
end)
game.onevent(defines.events.ontick, function(event) -- ran ~60 times per second
if #glob.trees > 0 then
for index, tree in ipairs(glob.trees[glob.trees.start]) do
if tree.valid and tree.health ~= glob.trees.health[tree.name] then
-- increment health based on how many areas there are between increments
tree.health = tree.health + 0.1 * #glob.trees
elseif not tree.valid then
table.remove(glob.trees[glob.trees.start], index) -- remove trees that no longer exist
end
end
-- increment start so that the next area is searched...
-- using % so it stays within bounds of the tree table and adding 1
-- because lua tables are 1 based instead of 0 based.
glob.trees.start = ((glob.trees.start + 1) % #glob.trees) + 1
end
end)
Code: Select all
remote.addinterface("some_interface_name_usually_mod_name", {
addArea = function(wasWarned)
if not wasWarned then
for _, player in ipairs(game.players) do
player.print("addArea will fail if there is more than 1 player on!\nTo continue call by adding true to the end of the call")
end
end
-- table with area since we're 'pretending' to be the onchunkgenerated event that it was originally written for
local pos = game.player.position
addArea({ area={ {pos.x - 100, pos.y - 100}, {pos.x + 100, pos.y + 100} } })
end
})
There is not, to my knowledge, any provided function that can do that. That is essentially what the onchunkgenerated event function is doing for us, adding trees in new chunks (base trees don't reproduce so no need to recheck them) to our own table in the glob table (the only table that is saved and loaded when the player's game is).Taehl wrote:call a function which gets a list of all trees in the map
It's not particularly difficult, but it requires some thought as to the "best" way to implement it.Taehl wrote:That is, indeed, less than easy
So far it hasn't actually been needed when a modicum of thought is put into the scripts (in this case, trying to loop over every tree in a new world drops UPS to 1/2, vs a very slight optimization with practically no thought put into it of only one "chunk" per tick gives a nice solid 60 UPS. Let alone your suggestion of calling a function to get all of the trees every minute) and, more importantly, it would take developer time away from the more important work on the game itself. Also (minor note), it doesn't fully support Lua 5.2 which is what's used in Factorio.Taehl wrote:Maybe they should implement LuaJIT, so mods won't be that slow.
As another option, one could ask drs really nicely to raise a custom event when his mod places a tree? or maybe when the tree is placed outside of areas that get automatically harvested. His trees consume pollution too, someone might try artificial forests after all.FreeER wrote: you'd need the code to recall findentitiesfiltered to see when more have grown, BUT that call is also relatively slow since the C++ has to first find all of the entities in that area, filter them, and then pass them back to Lua, so you wouldn't want to call it for areas that don't have a treefarm in them (you can detect when they are built with onbuiltentity and onrobotbuiltentity). You'd probably want to make 'special' areas that are, perhaps, checked more frequently using findentitiesfiltered (separate list, just storing the area to check instead of the trees theirselves?).
Hm, I'm honestly not certain since all of my Lua experience has been with Factorio and I've never really worried about optimization much, but my, um, logical hypothesis, is that the for loop would be a bit faster since it removes the need for a method/function call. Of course with that reasoning your second option would be slightly slower than your first, but possibly faster than my suggestion. I'm not sure of the actual difference, but do keep in mind that with the hard-coded table that you can no longer work with mod-added trees (though you could generate that table on load by looping through game.entityprototypes and checking if the type == "tree" and ...). Not sure how to bench mark it though... a quick test with os.time() in a regular lua environment (outside Factorio) just results in 0 for all three.Adil wrote:I wonder
TrueAdil wrote:one could ask drs really nicely to raise a custom event