Overview
Comment: | replace hellaciously overcomplicated function with simpler, faster one |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
5322b9e068dad4419fbb638dffd89260 |
User & Date: | lexi on 2021-07-06 04:18:54 |
Other Links: | manifest | tags |
Context
2021-07-06
| ||
04:32 | fix sap interval check-in: ecfe4b244e user: lexi tags: trunk | |
04:18 | replace hellaciously overcomplicated function with simpler, faster one check-in: 5322b9e068 user: lexi tags: trunk | |
2021-07-05
| ||
23:59 | add more recipes and god gifts check-in: 049207a61e user: lexi tags: trunk | |
Changes
Modified lib/node.lua from [3dbeb921b1] to [483baaca72].
1 1 local log = sorcery.logger('lib.node') 2 2 local ofs = { 3 3 neighbors = { 4 + {x = 0, y = 1, z = 0}; 5 + {x = 0, y = -1, z = 0}; 4 6 {x = 1, y = 0, z = 0}; 5 7 {x = -1, y = 0, z = 0}; 6 - {x = 0, y = 1, z = 0}; 7 - {x = 0, y = -1, z = 0}; 8 8 {x = 0, y = 0, z = 1}; 9 9 {x = 0, y = 0, z = -1}; 10 10 }; 11 11 planecorners = { 12 12 {x = 1, y = 0, z = 1}; 13 13 {x = -1, y = 0, z = 1}; 14 14 {x = -1, y = 0, z = -1}; ................................................................................ 188 188 -- various problems could be avoided by unconditionally inserted the meta key, 189 189 -- or inserting it also when it comes into contact with another trunk node, 190 190 -- but pepole use these things to build with and that is just way way too many 191 191 -- meta keys for me to consider it an option. 192 192 -- 193 193 -- verdict: not very good, but decent enough for most cases. mtg should have 194 194 -- done better than this, but now we're all stuck with their bullshit 195 + -- 196 + -- UPDATE: in pratice this is way too expensive to be functional, and causes servers to hang. we're replacing it with a simpler version 195 197 196 198 local treetype = force(pos).name 197 199 if minetest.get_item_group(treetype, 'tree') == 0 then -- sir this is not a tree 198 200 return nil -- 無 199 201 end 200 202 local treedef = sorcery.lib.tbl.select(sorcery.data.trees, 'node', treetype) 201 203 local leaftype = treedef and treedef.leaves or nil 204 + if not leaftype then return false end 205 + 202 206 local uppermost, lowermost 207 + local found_leaves = false 203 208 204 209 local treemap, treenodes = amass(pos,function(node, where) 205 - if node.name == treetype then 206 - -- abuse predicate function to also track y minimum, so we can 207 - -- avoid iterating over it all later again -- this function is 208 - -- expensive enough already 209 - if (not lowermost) or where.y < lowermost then 210 - lowermost = where.y 210 + print(where, 'treetype',treetype,'node',node.name,node.param1,node.param2) 211 + if node.name == treetype and node.param1 == 0 then 212 + -- abuse predicate so we can avoid iterating over it all later 213 + -- again -- this function is expensive enough already 214 + if (not lowermost) or where.y < lowermost.y then 215 + lowermost = where 211 216 end 212 - if (not uppermost) or where.y > uppermost then 213 - uppermost = where.y 217 + 218 + if (not uppermost) or where.y > uppermost.y then 219 + uppermost = where 214 220 end 215 - local m=minetest.get_meta(where) 216 - if m:get_int('sorcery:trunk_node_role') ~= 1 then 217 - return true 218 - else 219 - log.warn('found a log node!') 220 - return false 221 - end 222 - end 223 - if leaftype == nil then 224 - if minetest.get_item_group(node.name, 'leaves') ~= 0 and node.param2 == 0 then 225 - log.warn('guessing leaf node for tree',treetype,'is',node.name,'; please report this bug to the mod responsible for this tree and ask for appropriate Sorcery interop code to be added') 226 - leaftype = node.name 227 - return true 228 - end 229 - elseif leaftype == node.name and node.param2 == 0 then 230 221 return true 222 + elseif not found_leaves and node.name == leaftype and node.param2 == 0 then 223 + found_leaves = true 231 224 end 232 225 return false 233 - end,ofs.adjoining) 234 - 235 - if leaftype == nil then return false end 236 - 237 - local trunkmap, trunknodes = amass(pos, {treetype}, ofs.adjoining) 238 - if treenodes[leaftype] == nil then return false end 239 - 240 - local cache = {} 241 - local uppermost_check_leaves = true 242 - local topnode 243 - for _, p in pairs(treenodes[treetype]) do 244 - -- if not sorcery.lib.tbl.select(trunknodes[treetype], function(v) 245 - -- return vector.equals(p, v) 246 - -- end, cache) then 247 - -- log.act('tree node', p, 'not accounted for in trunk!') 248 - -- return false 249 - -- end 250 - if p.y == uppermost and uppermost_check_leaves then 251 - topnode = p 252 - uppermost_check_leaves = false 253 - end 254 - if p.y == lowermost then 255 - -- this is the bottom of the tree, bail if it's in not full contact 256 - -- with soil or other eligible nodes as determined by the tree def's 257 - -- 'rooted' predicate 258 - local beneath = vector.offset(p, 0,-1,0); 259 - if treedef.rooted then 260 - if not treedef.rooted { 261 - trunk = p; 262 - groundpos = beneath; 263 - ground = force(beneath); 264 - treemap = treemap; 265 - treenodes = treenodes; 266 - } then return false end 267 - else 268 - if minetest.get_item_group(force(beneath).name, 'soil') == 0 then 269 - return false 270 - end 271 - end 226 + end, ofs.adjoining) 227 + 228 + if not found_leaves then return false end 229 + 230 + -- do -- leaf search 231 + -- local pss, ct = minetest.find_nodes_in_area(uppermost:offset(-1,0,-1), uppermost:offset(1,1,1), leaftype) 232 + -- if ct[leaftype] >= 1 then 233 + -- for _, p in pairs(pss) do 234 + -- local ln = force(p) 235 + -- if ln.param2 == 0 then goto found_leaves end 236 + -- end 237 + -- end 238 + -- return false 239 + -- end 240 + 241 + ::found_leaves:: do -- soil check 242 + local beneath = force(lowermost:offset(0,-1,0)) 243 + if minetest.get_item_group(beneath.name, 'soil') == 0 then 244 + return false 272 245 end 273 246 end 274 247 275 - if uppermost_check_leaves then 276 - for _,p in pairs(treenodes[leaftype]) do 277 - if p.y == uppermost then 278 - topnode = p 279 - break 280 - end 281 - end 282 - end 283 - -- 284 - --make sure the tree gets enough light 285 - if checklight and minetest.get_natural_light(vector.offset(topnode,0,1,0), 0.5) < 13 then return false end 286 - 287 - -- other possible checks: make sure all ground-touching nodes are directly 288 - -- adjacent 248 + return true, {map = treemap, nodes = treenodes, trunk = treetype, leaves = leaftype, topnode = uppermost, roots = lowermost} 249 + 250 + -- if checklight then iterate to leaf top and check light 289 251 290 - return true, {map = treemap, nodes = treenodes, trunk = treetype, leaves = leaftype, topnode = topnode} 252 + -- local uppermost, lowermost 253 + -- 254 + -- local treemap, treenodes = amass(pos,function(node, where) 255 + -- if node.name == treetype then 256 + -- -- abuse predicate function to also track y minimum, so we can 257 + -- -- avoid iterating over it all later again -- this function is 258 + -- -- expensive enough already 259 + -- if (not lowermost) or where.y < lowermost then 260 + -- lowermost = where.y 261 + -- end 262 + -- if (not uppermost) or where.y > uppermost then 263 + -- uppermost = where.y 264 + -- end 265 + -- local m=minetest.get_meta(where) 266 + -- if m:get_int('sorcery:trunk_node_role') ~= 1 then 267 + -- return true 268 + -- else 269 + -- log.warn('found a log node!') 270 + -- return false 271 + -- end 272 + -- end 273 + -- if leaftype == nil then 274 + -- if minetest.get_item_group(node.name, 'leaves') ~= 0 and node.param2 == 0 then 275 + -- log.warn('guessing leaf node for tree',treetype,'is',node.name,'; please report this bug to the mod responsible for this tree and ask for appropriate Sorcery interop code to be added') 276 + -- leaftype = node.name 277 + -- return true 278 + -- end 279 + -- elseif leaftype == node.name and node.param2 == 0 then 280 + -- return true 281 + -- end 282 + -- return false 283 + -- end,ofs.adjoining) 284 + -- 285 + -- if leaftype == nil then return false end 286 + -- 287 + -- local trunkmap, trunknodes = amass(pos, {treetype}, ofs.adjoining) 288 + -- if treenodes[leaftype] == nil then return false end 289 + -- 290 + -- local cache = {} 291 + -- local uppermost_check_leaves = true 292 + -- local topnode 293 + -- for _, p in pairs(treenodes[treetype]) do 294 + -- -- if not sorcery.lib.tbl.select(trunknodes[treetype], function(v) 295 + -- -- return vector.equals(p, v) 296 + -- -- end, cache) then 297 + -- -- log.act('tree node', p, 'not accounted for in trunk!') 298 + -- -- return false 299 + -- -- end 300 + -- if p.y == uppermost and uppermost_check_leaves then 301 + -- topnode = p 302 + -- uppermost_check_leaves = false 303 + -- end 304 + -- if p.y == lowermost then 305 + -- -- this is the bottom of the tree, bail if it's in not full contact 306 + -- -- with soil or other eligible nodes as determined by the tree def's 307 + -- -- 'rooted' predicate 308 + -- local beneath = vector.offset(p, 0,-1,0); 309 + -- if treedef.rooted then 310 + -- if not treedef.rooted { 311 + -- trunk = p; 312 + -- groundpos = beneath; 313 + -- ground = force(beneath); 314 + -- treemap = treemap; 315 + -- treenodes = treenodes; 316 + -- } then return false end 317 + -- else 318 + -- if minetest.get_item_group(force(beneath).name, 'soil') == 0 then 319 + -- return false 320 + -- end 321 + -- end 322 + -- end 323 + -- end 324 + -- 325 + -- if uppermost_check_leaves then 326 + -- for _,p in pairs(treenodes[leaftype]) do 327 + -- if p.y == uppermost then 328 + -- topnode = p 329 + -- break 330 + -- end 331 + -- end 332 + -- end 333 + -- -- 334 + -- --make sure the tree gets enough light 335 + -- if checklight and minetest.get_natural_light(vector.offset(topnode,0,1,0), 0.5) < 13 then return false end 336 + -- 337 + -- -- other possible checks: make sure all ground-touching nodes are directly 338 + -- -- adjacent 339 + -- 340 + -- return true, {map = treemap, nodes = treenodes, trunk = treetype, leaves = leaftype, topnode = topnode} 291 341 end; 292 342 293 343 get_arrival_point = function(pos) 294 344 local try = function(p) 295 345 local air = sorcery.lib.node.is_clear 296 346 if air(p) then 297 347 if air(vector.offset(p,0,1,0)) then return p end
Modified tap.lua from [43b3147bb9] to [87f184e80e].
89 89 end 90 90 end do 91 91 return 92 92 end ::found:: 93 93 94 94 local tposhash = minetest.hash_node_position(tpos) 95 95 local live, should_cache 96 - local mass_leaves, mass_trunk, topnode, prevalidate 96 + local mass_trunk, topnode, prevalidate 97 97 if abm_cache.treehash[tposhash] then 98 98 live = true 99 99 local c = abm_cache.treehash[tposhash] 100 - mass_leaves = c.mass_leaves 100 + -- mass_leaves = c.mass_leaves 101 101 mass_trunk = c.mass_trunk 102 102 prevalidate = true 103 103 else 104 104 local tbody 105 105 live, tbody = sorcery.lib.node.tree_is_live(tpos) 106 106 if live then 107 107 should_cache = tbody.nodes[tbody.trunk] 108 - mass_leaves = #(tbody.nodes[tbody.leaves]) 108 + -- mass_leaves = #(tbody.nodes[tbody.leaves]) 109 109 mass_trunk = #(tbody.nodes[tbody.trunk]) * 12 110 110 topnode = tbody.topnode 111 111 end 112 112 end 113 113 114 114 if (not live) 115 115 or tree.sap == false 116 116 or not tree.sapliq then return end 117 117 if mass_trunk < 12*3 then return end -- too small 118 118 119 119 tapdrip(tree.sapliq,pos) 120 120 121 - local mass = mass_leaves + mass_trunk 122 - local max_mass = 400 123 - local ltratio = mass_leaves / mass_trunk 124 - local mratio = mass / max_mass 125 - local outof = 15 / mratio 126 - local chance = math.max(1, math.floor(outof - (25 * ltratio))) / 3 127 - local diceroll = math.random(1,chance) 121 + local mass = mass_trunk -- + mass_leaves 122 + local max_mass = 250 -- 400 123 + -- local ltratio = mass_leaves / mass_trunk 124 + -- local mratio = mass / max_mass 125 + -- local outof = 15 / mratio 126 + -- local chance = math.max(1, math.floor(outof - (25 * ltratio))) / 3 127 + local chance = mass / max_mass 128 + local diceroll = math.random(1,math.ceil(chance)) 128 129 -- log.act('rolling dice: ', chance,diceroll, '(lt ratio =', ltratio, '; mass ratio = ', mratio, '; tree mass =', mass, '; outof =', outof) 129 130 if diceroll ~= 1 then return end -- failed roll 130 131 131 - if not prevalidate then 132 - if minetest.get_natural_light(vector.offset(topnode,0,1,0), 0.5) < 13 133 - then return false end 134 - end 132 + -- if not prevalidate then 133 + -- if minetest.get_natural_light(vector.offset(topnode,0,1,0), 0.5) < 13 134 + -- then return false end 135 + -- end 136 + -- FIXME 135 137 136 138 for i=1,8 do 137 139 local at = vector.offset(pos, 0,-i,0) 138 140 if sorcery.lib.node.is_air(at) then goto skip end 139 141 140 142 local trough = minetest.get_node(at) 141 143 if minetest.get_item_group(trough.name, 'sorcery_trough') ~= 0 then ................................................................................ 158 160 else 159 161 node.name = nct.make((ctr.charge or 0) + nct.res,1):get_name() 160 162 end 161 163 minetest.swap_node(at, node) 162 164 end 163 165 if should_cache then 164 166 for _,v in pairs(should_cache) do 165 - abm_cache.treehash[v:to_string()] = { 166 - mass_leaves = mass_leaves; 167 + abm_cache.treehash[minetest.hash_node_position(v)] = { 168 + -- mass_leaves = mass_leaves; 167 169 mass_trunk = mass_trunk; 168 170 } 169 171 end 170 172 end 171 173 end 172 174 else 173 175 log.err('item',trough.name,'is marked as a trough but lacks a _sorcery.container property table') 174 176 end 175 177 end 176 178 do return end 177 179 ::skip::end 178 180 end; 179 181 }
Modified tree.lua from [95c6839cbe] to [e171bc2182].
16 16 -- generates sap and hooks handlers appropriately 17 17 if t.node then 18 18 local def = minetest.registered_nodes[t.node] 19 19 local nextfn = def.on_place 20 20 minetest.override_item(t.node, { on_place = function(stack, who, pointed, ...) 21 21 if nextfn then nextfn(stack, who, pointed, ...) end 22 22 if who ~= nil and pointed.type == 'node' then 23 - local pos = pointed.above 24 - local _, counts = minetest.find_nodes_in_area( 25 - vector.offset(pos, -1,-1,-1), 26 - vector.offset(pos, 1, 1, 1), 27 - t.leaves or 'group:leaves', false) 28 - if counts[next(counts)] > 0 then 29 - minetest.get_meta(pos):set_int('sorcery:trunk_node_role', 1) 30 - end 23 + -- local pos = pointed.above 24 + -- local _, counts = minetest.find_nodes_in_area( 25 + -- vector.offset(pos, -1,-1,-1), 26 + -- vector.offset(pos, 1, 1, 1), 27 + -- t.leaves or 'group:leaves', false) 28 + -- if counts[next(counts)] > 0 then 29 + local n = minetest.get_node(pointed.above) 30 + n.param1 = 1 31 + minetest.swap_node(pointed.above, n) 32 + -- end 31 33 end 32 34 end }) 33 35 end 34 36 35 37 if t.sap == false then return end 36 38 if not t.sapliq then 37 39 t.sapliq = string.format('sorcery:sap_%s', id)