12 Commits

Author SHA1 Message Date
3228cec1ae Merge remote-tracking branch 'upstream/master' 2024-09-15 13:00:59 +02:00
f400a91e90 Remove functions which are deprecated and which I do not recommend to use
Removing deprecated functionality can help to clean up the code a bit.

I remove the following deprecated functions and values:
* vector.zero
* vector.plane()
* vector.pos_to_string()
* vector.quickadd()
* vector.scalar()
* vector.get_data_from_pos()
* vector.set_data_to_pos()
* vector.set_data_to_pos_optional()
* vector.remove_data_from_pos()
* vector.get_data_pos_table()

Furthermore, I remove the unused, experimental vector_meta.lua file
and make luacheck linting more strict so that it can show accidental
uses of deprecated functions in the code of this mod if there are any.

This change can break compatility with old mods which use vector_extras.
2024-08-27 17:38:30 +02:00
0501920345 Merge remote-tracking branch 'upstream/master' 2021-11-01 10:44:31 +01:00
63edf837d7 depends.txt -> mod.conf 2021-10-10 12:57:57 +02:00
9bf8a890c6 Merge remote-tracking branch 'upstream/master' 2021-09-21 23:13:15 +02:00
ed6b514057 Make vector.zero callable
This is needed to keep compatibility with new minetest builtin code
2021-09-05 19:04:02 +02:00
374735b17f Merge remote-tracking branch 'upstream/master' 2021-03-12 12:41:19 +01:00
f8c12047d5 Add .luacheckrc and some code cleanup 2021-03-01 20:37:59 +01:00
fdbcc2e425 A small comment 2021-03-01 19:26:24 +01:00
2f0ad734d4 Merge remote-tracking branch 'upstream/master' 2020-08-25 20:07:10 +02:00
8c7aaf6c0b Fix a bug in deprecated vector.plane 2020-08-25 11:03:17 +02:00
e826bbd9b9 Replace vector.scalar with vector.dot 2020-08-25 11:03:17 +02:00
6 changed files with 64 additions and 493 deletions

11
.luacheckrc Normal file
View File

@ -0,0 +1,11 @@
read_globals = {
-- Defined by Minetest
"minetest", "PseudoRandom", "VoxelArea", "string", "dump", "math",
vector = {
fields = {
"add", "cross", "direction", "distance", "dot", "multiply",
"new", "normalize", "round", "subtract",
"from_number", "get_max_coord", "twoline", "threeline", "rayIter"
}
}
}

18
doc.md
View File

@ -134,21 +134,3 @@ See e.g. `minetest.line_of_sight`.
* If `time` is omitted, it uses the current time. * If `time` is omitted, it uses the current time.
* This function does not yet support the moon; * This function does not yet support the moon;
at night it simply returns `nil`. at night it simply returns `nil`.
## Helpers which I don't recommend to use now
* `vector.pos_to_string(pos)`: returns a string
* It is similar to `minetest.pos_to_string`; it uses a different format:
`"("..pos.x.."|"..pos.y.."|"..pos.z..")"`
* `vector.zero`
* The zero vector `{x=0, y=0, z=0}`
* `vector.quickadd(pos, [z],[y],[x])`
* Adds values to the vector components in-place
## Deprecated helpers
* `vector.plane`
* should be removed soon; it should have done the same as vector.triangle

250
init.lua
View File

@ -2,10 +2,6 @@ local path = minetest.get_modpath"vector_extras"
local funcs = {} local funcs = {}
function funcs.pos_to_string(pos)
return "("..pos.x.."|"..pos.y.."|"..pos.z..")"
end
local r_corr = 0.25 --remove a bit more nodes (if shooting diagonal) to let it local r_corr = 0.25 --remove a bit more nodes (if shooting diagonal) to let it
-- look like a hole (sth like antialiasing) -- look like a hole (sth like antialiasing)
@ -52,6 +48,7 @@ local function return_line(pos, dir, range) --range ~= length
local num = 1 local num = 1
local t_dir = get_used_dir(dir) local t_dir = get_used_dir(dir)
local dir_typ = t_dir[1] local dir_typ = t_dir[1]
local f_tab
if t_dir[3] == "+" then if t_dir[3] == "+" then
f_tab = {0, range, 1} f_tab = {0, range, 1}
else else
@ -122,7 +119,7 @@ function funcs.rayIter(pos, dir)
for i in pairs(step) do for i in pairs(step) do
choose[i] = vector.new(p) choose[i] = vector.new(p)
choose[i][i] = choose[i][i] + step[i] choose[i][i] = choose[i][i] + step[i]
choosefit[i] = vector.scalar(vector.normalize(vector.subtract(choose[i], pos)), dir) choosefit[i] = vector.dot(vector.normalize(vector.subtract(choose[i], pos)), dir)
end end
p = choose[vector.get_max_coord(choosefit)] p = choose[vector.get_max_coord(choosefit)]
@ -269,63 +266,6 @@ function funcs.pnorm(v, p)
return (math.abs(v.x)^p + math.abs(v.y)^p + math.abs(v.z)^p)^(1 / p) return (math.abs(v.x)^p + math.abs(v.y)^p + math.abs(v.z)^p)^(1 / p)
end end
--not optimized
--local areas = {}
function funcs.plane(ps)
-- sort positions and imagine the first one (A) as vector.zero
ps = vector.sort_positions(ps)
local pos = ps[1]
local B = vector.subtract(ps[2], pos)
local C = vector.subtract(ps[3], pos)
-- get the positions for the fors
local cube_p1 = {x=0, y=0, z=0}
local cube_p2 = {x=0, y=0, z=0}
for i in pairs(cube_p1) do
cube_p1[i] = math.min(B[i], C[i], 0)
cube_p2[i] = math.max(B[i], C[i], 0)
end
cube_p1 = vector.apply(cube_p1, math.floor)
cube_p2 = vector.apply(cube_p2, math.ceil)
local vn = vector.normalize(vector.cross(B, C))
local nAB = vector.normalize(B)
local nAC = vector.normalize(C)
local angle_BAC = math.acos(vector.scalar(nAB, nAC))
local nBA = vector.multiply(nAB, -1)
local nBC = vector.normalize(vector.subtract(C, B))
local angle_ABC = math.acos(vector.scalar(nBA, nBC))
for z = cube_p1.z, cube_p2.z do
for y = cube_p1.y, cube_p2.y do
for x = cube_p1.x, cube_p2.x do
local p = {x=x, y=y, z=z}
local n = -vector.scalar(p, vn)/vector.scalar(vn, vn)
if math.abs(n) <= 0.5 then
local ep = vector.add(p, vector.multiply(vn, n))
local nep = vector.normalize(ep)
local angle_BAep = math.acos(vector.scalar(nAB, nep))
local angle_CAep = math.acos(vector.scalar(nAC, nep))
local angldif = angle_BAC - (angle_BAep+angle_CAep)
if math.abs(angldif) < 0.001 then
ep = vector.subtract(ep, B)
nep = vector.normalize(ep)
local angle_ABep = math.acos(vector.scalar(nBA, nep))
local angle_CBep = math.acos(vector.scalar(nBC, nep))
local angldif = angle_ABC - (angle_ABep+angle_CBep)
if math.abs(angldif) < 0.001 then
table.insert(ps, vector.add(pos, p))
end
end
end
end
end
end
return ps
end
function funcs.straightdelay(s, v, a) function funcs.straightdelay(s, v, a)
if not a then if not a then
return s/v return s/v
@ -333,8 +273,6 @@ function funcs.straightdelay(s, v, a)
return (math.sqrt(v*v+2*a*s)-v)/a return (math.sqrt(v*v+2*a*s)-v)/a
end end
vector.zero = vector.new()
function funcs.sun_dir(time) function funcs.sun_dir(time)
if not time then if not time then
time = minetest.get_timeofday() time = minetest.get_timeofday()
@ -358,9 +296,9 @@ function funcs.inside(pos, minp, maxp)
return true return true
end end
function funcs.minmax(p1, p2) function funcs.minmax(pos1, pos2)
local p1 = vector.new(p1) local p1 = vector.new(pos1)
local p2 = vector.new(p2) local p2 = vector.new(pos2)
for _,i in ipairs({"x", "y", "z"}) do for _,i in ipairs({"x", "y", "z"}) do
if p1[i] > p2[i] then if p1[i] > p2[i] then
p1[i], p2[i] = p2[i], p1[i] p1[i], p2[i] = p2[i], p1[i]
@ -390,7 +328,7 @@ end
local adammil_fill = dofile(path .. "/adammil_flood_fill.lua") local adammil_fill = dofile(path .. "/adammil_flood_fill.lua")
function funcs.search_2d(go_test, x0, y0, allow_revisit, give_map) function funcs.search_2d(go_test, x0, y0, allow_revisit, give_map)
marked_places = adammil_fill(go_test, x0, y0, allow_revisit) local marked_places = adammil_fill(go_test, x0, y0, allow_revisit)
if give_map then if give_map then
return marked_places return marked_places
end end
@ -406,7 +344,7 @@ end
local fallings_search = dofile(path .. "/fill_3d.lua") local fallings_search = dofile(path .. "/fill_3d.lua")
local moves_touch = { local moves_touch = {
{x = -1, y = 0, z = 0}, {x = -1, y = 0, z = 0},
{x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0}, -- FIXME should this be here?
{x = 1, y = 0, z = 0}, {x = 1, y = 0, z = 0},
{x = 0, y = -1, z = 0}, {x = 0, y = -1, z = 0},
{x = 0, y = 1, z = 0}, {x = 0, y = 1, z = 0},
@ -498,7 +436,8 @@ function funcs.explosion_perlin(rmin, rmax, nparams)
nparams.spread = nparams.spread or vector.from_number(r*5) nparams.spread = nparams.spread or vector.from_number(r*5)
local pos = {x=math.random(-30000, 30000), y=math.random(-30000, 30000), z=math.random(-30000, 30000)} local pos = {x=math.random(-30000, 30000), y=math.random(-30000, 30000), z=math.random(-30000, 30000)}
local map = minetest.get_perlin_map(nparams, vector.from_number(r+r+1)):get3dMap_flat(pos) local map = minetest.get_perlin_map(nparams, vector.from_number(r+r+1)
):get3dMap_flat(pos)
local id = 1 local id = 1
@ -513,11 +452,11 @@ function funcs.explosion_perlin(rmin, rmax, nparams)
local tab, n = {}, 1 local tab, n = {}, 1
for z=-r,r do for z=-r,r do
local bare_dist = z*z local bare_dist_z = z*z
for y=-r,r do for y=-r,r do
local bare_dist = bare_dist+y*y local bare_dist_yz = bare_dist_z + y*y
for x=-r,r do for x=-r,r do
local bare_dist = bare_dist+x*x local bare_dist = bare_dist_yz + x*x
local add = bare_dist < bare_mindist local add = bare_dist < bare_mindist
local pval, distdiv local pval, distdiv
if not add if not add
@ -543,22 +482,19 @@ function funcs.explosion_perlin(rmin, rmax, nparams)
end end
end end
map = nil
collectgarbage()
-- change strange values -- change strange values
local pval_diff = pval_max - pval_min local pval_diff = pval_max - pval_min
pval_min = pval_min/pval_diff pval_min = pval_min/pval_diff
for n,i in pairs(tab) do for k,i in pairs(tab) do
if i[2] then if i[2] then
local new_pval = math.abs(i[2]/pval_diff - pval_min) local new_pval = math.abs(i[2]/pval_diff - pval_min)
if i[3]+0.33 < new_pval then if i[3]+0.33 < new_pval then
tab[n] = {i[1]} tab[k] = {i[1]}
elseif i[3] < new_pval then elseif i[3] < new_pval then
tab[n] = {i[1], true} tab[k] = {i[1], true}
else else
tab[n] = nil tab[k] = nil
end end
end end
end end
@ -633,67 +569,6 @@ function funcs.ring(r)
return tab2 return tab2
end end
--~ posy(t) = att + bt + c
--~ vely(t) = 2at + b
--~ accy(t) = 2a
--~ a = -0.5gravity
--~ vely(0) = b = vel.y
--~ posy(0) = c = pos.y
--~ posy(t) = -0.5 * gravity * t * t + vel.y * t + pos.y
--~ vely(t) = -gravity*t + vel.y
--~ Scheitel:
--~ vely(t) = 0 = -gravity*t + vel.y
--~ t = vel.y / gravity
--~ 45°
--~ vely(t)^2 = velx(t)^2 + velz(t)^2
--~ (-gravity*t + vel.y)^2 = vel.x * vel.x + vel.z * vel.z
--~ gravity^2 * t^2 + vel.y^2 - -2*gravity*t*vel.y = vel.x * vel.x + vel.z * vel.z
--~ gravity^2 * t^2 - 2*gravity*vel.y * t + (vel.y^2 - vel.x^2 - vel.z^2) = 0
--~ t = (2*gravity*vel.y .. rt((2*gravity*vel.y)^2 - 4*gravity^2*(vel.y^2 - vel.x^2 - vel.z^2))) / (2*gravity^2)
--~ t = (2*gravity*vel.y .. rt(4*gravity^2*vel.y^2 - 4*gravity^2*(vel.y^2) + 4*gravity^2*(vel.x^2 + vel.z^2))) / (2*gravity^2)
--~ t = (2*gravity*vel.y .. 2*gravity*rt(vel.x^2 + vel.z^2)) / (2*gravity^2)
--~ t = (vel.y .. rt(vel.x^2 + vel.z^2)) / gravity
--~ t1 = (vel.y - math.sqrt(vel.x * vel.x + vel.z * vel.z)) / gravity
--~ t2 = (vel.y + math.sqrt(vel.x * vel.x + vel.z * vel.z)) / gravity
--~ yswitch = posy(t1) (= posy(t2)) //links und rechts gleich
--~ yswitch = -0.5 * gravity * ((vel.y + math.sqrt(vel.x * vel.x + vel.z * vel.z)) / gravity)^2 + vel.y * ((vel.y + math.sqrt(vel.x * vel.x + vel.z * vel.z)) / gravity) + pos.y
--~ yswitch = -0.5 * gravity * (vel.y + math.sqrt(vel.x * vel.x + vel.z * vel.z))^2 / gravity^2 + vel.y * ((vel.y + math.sqrt(vel.x * vel.x + vel.z * vel.z)) / gravity) + pos.y
--~ yswitch = -0.5 * (vel.y^2 + 2*vel.y*math.sqrt(vel.x * vel.x + vel.z * vel.z) + vel.x^2 + vel.z^2) / gravity + ((vel.y^2 + vel.y*math.sqrt(vel.x * vel.x + vel.z * vel.z)) / gravity) + pos.y
--~ yswitch = (-0.5 * (vel.y^2 + 2*vel.y*math.sqrt(vel.x * vel.x + vel.z * vel.z) + vel.x^2 + vel.z^2) + ((vel.y^2 + vel.y*math.sqrt(vel.x * vel.x + vel.z * vel.z)))) / gravity + pos.y
--~ yswitch = (-0.5 * vel.y^2 - vel.y*math.sqrt(vel.x * vel.x + vel.z * vel.z) - 0.5 * vel.x^2 - 0.5 * vel.z^2 + vel.y^2 + vel.y*math.sqrt(vel.x * vel.x + vel.z * vel.z)) / gravity + pos.y
--~ yswitch = (-0.5 * vel.y^2 - 0.5 * vel.x^2 - 0.5 * vel.z^2 + vel.y^2) / gravity + pos.y
--~ yswitch = (0.5 * vel.y^2 - 0.5 * vel.x^2 - 0.5 * vel.z^2) / gravity + pos.y
--~ yswitch = -0.5 * (vel.x * vel.x + vel.z * vel.z - vel.y * vel.y) / gravity + pos.y
--~ 45° Zeitpunkte kleineres beim Aufstieg, größeres beim Fall
--~ (-gravity*t + vel.y)^2 = vel.x * vel.x + vel.z * vel.z
--~ -gravity*t + vel.y = ..math.sqrt(vel.x * vel.x + vel.z * vel.z)
--~ t = (..math.sqrt(vel.x * vel.x + vel.z * vel.z) + vel.y) / gravity
--~ t_raise = (-math.sqrt(vel.x * vel.x + vel.z * vel.z) + vel.y) / gravity
--~ t_fall = (math.sqrt(vel.x * vel.x + vel.z * vel.z) + vel.y) / gravity
--~ posy nach t umstellen
--~ y = -0.5 * gravity * t * t + vel.y * t + pos.y
--~ 0 = -0.5 * gravity * t * t + vel.y * t + pos.y - y
--~ t = (-vel.y .. math.sqrt(vel.y^2 + 2 * gravity * (pos.y - y))) / (-gravity)
--~ t = (vel.y .. math.sqrt(vel.y^2 + 2 * gravity * (pos.y - y))) / gravity
--~ t_up = (vel.y - math.sqrt(vel.y^2 + 2 * gravity * (pos.y - y))) / gravity
--~ t_down = (vel.y + math.sqrt(vel.y^2 + 2 * gravity * (pos.y - y))) / gravity
--~ posx(t) = vel.x * t + pos.x
--~ posz(t) = vel.z * t + pos.z
--~ posx nach t umstellen
--~ posx - pos.x = vel.x * t
--~ t = (posx - pos.x) / vel.x
local function get_parabola_points(pos, vel, gravity, waypoints, max_pointcount, local function get_parabola_points(pos, vel, gravity, waypoints, max_pointcount,
time) time)
local pointcount = 0 local pointcount = 0
@ -703,9 +578,9 @@ local function get_parabola_points(pos, vel, gravity, waypoints, max_pointcount,
/ gravity + pos.y / gravity + pos.y
-- the times of the 45° angle point -- the times of the 45° angle point
local i = math.sqrt(vel.x^2 + vel.z^2) local vel_len = math.sqrt(vel.x^2 + vel.z^2)
local t_raise_end = (-i + vel.y) / gravity local t_raise_end = (-vel_len + vel.y) / gravity
local t_fall_start = (i + vel.y) / gravity local t_fall_start = (vel_len + vel.y) / gravity
if t_fall_start > 0 then if t_fall_start > 0 then
-- the right 45° angle point wasn't passed yet -- the right 45° angle point wasn't passed yet
if t_raise_end > 0 then if t_raise_end > 0 then
@ -834,11 +709,11 @@ function funcs.throw_parabola(pos, vel, gravity, point_count, time)
-- get a list of possible positions between -- get a list of possible positions between
local diff = vector.subtract(p2, p) local diff = vector.subtract(p2, p)
local possible_positions = {} local possible_positions = {}
for i,v in pairs(diff) do for c,v in pairs(diff) do
if v ~= 0 then if v ~= 0 then
local p = vector.new(p) local pos_moved = vector.new(p)
p[i] = p[i] + v pos_moved[c] = pos_moved[c] + v
possible_positions[#possible_positions+1] = p possible_positions[#possible_positions+1] = pos_moved
end end
end end
-- test which one fits best -- test which one fits best
@ -849,12 +724,12 @@ function funcs.throw_parabola(pos, vel, gravity, point_count, time)
z = vel.z * t + pos.z, z = vel.z * t + pos.z,
} }
local d = math.huge local d = math.huge
for i = 1,2 do for k = 1,2 do
local pos = possible_positions[i] local pos_moved = possible_positions[k]
local dist = vector.distance(pos, near_p) local dist_current = vector.distance(pos_moved, near_p)
if dist < d then if dist_current < d then
p = pos p = pos_moved
d = dist d = dist_current
end end
end end
-- add it -- add it
@ -865,11 +740,11 @@ function funcs.throw_parabola(pos, vel, gravity, point_count, time)
-- get a list of possible positions between -- get a list of possible positions between
local diff = vector.subtract(p2, p) local diff = vector.subtract(p2, p)
local possible_positions = {} local possible_positions = {}
for i,v in pairs(diff) do for c,v in pairs(diff) do
if v ~= 0 then if v ~= 0 then
local p = vector.new(p) local pos_moved = vector.new(p)
p[i] = p[i] + v pos_moved[c] = pos_moved[c] + v
possible_positions[#possible_positions+1] = p possible_positions[#possible_positions+1] = pos_moved
end end
end end
-- test which one fits best -- test which one fits best
@ -881,12 +756,12 @@ function funcs.throw_parabola(pos, vel, gravity, point_count, time)
} }
local d = math.huge local d = math.huge
assert(#possible_positions == 4-k, "how, number positions?") assert(#possible_positions == 4-k, "how, number positions?")
for i = 1,4-k do for j = 1,4-k do
local pos = possible_positions[i] local pos_moved = possible_positions[j]
local dist = vector.distance(pos, near_p) local dist_current = vector.distance(pos_moved, near_p)
if dist < d then if dist_current < d then
p = pos p = pos_moved
d = dist d = dist_current
end end
end end
-- add it -- add it
@ -907,9 +782,9 @@ function funcs.chunkcorner(pos)
return {x=pos.x-pos.x%16, y=pos.y-pos.y%16, z=pos.z-pos.z%16} return {x=pos.x-pos.x%16, y=pos.y-pos.y%16, z=pos.z-pos.z%16}
end end
function funcs.point_distance_minmax(p1, p2) function funcs.point_distance_minmax(pos1, pos2)
local p1 = vector.new(p1) local p1 = vector.new(pos1)
local p2 = vector.new(p2) local p2 = vector.new(pos2)
local min, max, vmin, vmax, num local min, max, vmin, vmax, num
for _,i in ipairs({"x", "y", "z"}) do for _,i in ipairs({"x", "y", "z"}) do
num = math.abs(p1[i] - p2[i]) num = math.abs(p1[i] - p2[i])
@ -926,21 +801,20 @@ function funcs.point_distance_minmax(p1, p2)
end end
function funcs.collision(p1, p2) function funcs.collision(p1, p2)
local clear, node_pos, collision_pos, max, dmax, dcmax, pt local clear, node_pos = minetest.line_of_sight(p1, p2)
clear, node_pos = minetest.line_of_sight(p1, p2)
if clear then if clear then
return false return false
end end
collision_pos = {} local collision_pos = {}
min, max = funcs.point_distance_minmax(node_pos, p2) local _, max = funcs.point_distance_minmax(node_pos, p2)
if node_pos[max] > p2[max] then if node_pos[max] > p2[max] then
collision_pos[max] = node_pos[max] - 0.5 collision_pos[max] = node_pos[max] - 0.5
else else
collision_pos[max] = node_pos[max] + 0.5 collision_pos[max] = node_pos[max] + 0.5
end end
dmax = p2[max] - node_pos[max] local dmax = p2[max] - node_pos[max]
dcmax = p2[max] - collision_pos[max] local dcmax = p2[max] - collision_pos[max]
pt = dcmax/dmax local pt = dcmax / dmax
for _,i in ipairs({"x", "y", "z"}) do for _,i in ipairs({"x", "y", "z"}) do
collision_pos[i] = p2[i] - (p2[i] - node_pos[i]) * pt collision_pos[i] = p2[i] - (p2[i] - node_pos[i]) * pt
@ -955,18 +829,6 @@ function funcs.update_minp_maxp(minp, maxp, pos)
end end
end end
function funcs.quickadd(pos, z,y,x)
if z then
pos.z = pos.z+z
end
if y then
pos.y = pos.y+y
end
if x then
pos.x = pos.x+x
end
end
function funcs.unpack(pos) function funcs.unpack(pos)
return pos.z, pos.y, pos.x return pos.z, pos.y, pos.x
end end
@ -1037,9 +899,9 @@ function funcs.triangle(pos1, pos2, pos3)
end end
-- https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/rasterization-stage -- https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/rasterization-stage
local function edgefunc(p1, p2, pos) local function edgefunc(vert1, vert2, pos)
return (pos[1] - p1[1]) * (p2[2] - p1[2]) return (pos[1] - vert1[1]) * (vert2[2] - vert1[2])
- (pos[2] - p1[2]) * (p2[1] - p1[1]) - (pos[2] - vert1[2]) * (vert2[1] - vert1[1])
end end
-- eps is used to prevend holes in neighbouring triangles -- eps is used to prevend holes in neighbouring triangles
-- It should be smaller than the smallest possible barycentric value -- It should be smaller than the smallest possible barycentric value
@ -1075,20 +937,12 @@ function funcs.triangle(pos1, pos2, pos3)
return points, n, barycentric_coords return points, n, barycentric_coords
end end
vector_extras_functions = funcs
dofile(path .. "/legacy.lua")
--dofile(minetest.get_modpath("vector_extras").."/vector_meta.lua")
vector_extras_functions = nil
for name,func in pairs(funcs) do for name,func in pairs(funcs) do
if vector[name] then if vector[name] then
minetest.log("error", "[vector_extras] vector."..name.. minetest.log("error", "[vector_extras] vector."..name..
" already exists.") " already exists.")
else else
-- luacheck: globals vector
vector[name] = func vector[name] = func
end end
end end

View File

@ -1,94 +0,0 @@
local funcs = vector_extras_functions
function funcs.scalar(v1, v2)
minetest.log("deprecated", "[vector_extras] vector.scalar is " ..
"deprecated, use vector.dot instead.")
return vector.dot(v1, v2)
end
function funcs.get_data_from_pos(tab, z,y,x)
minetest.log("deprecated", "[vector_extras] get_data_from_pos is " ..
"deprecated, use the minetest pos hash function instead.")
local data = tab[z]
if data then
data = data[y]
if data then
return data[x]
end
end
end
function funcs.set_data_to_pos(tab, z,y,x, data)
minetest.log("deprecated", "[vector_extras] set_data_to_pos is " ..
"deprecated, use the minetest pos hash function instead.")
if tab[z] then
if tab[z][y] then
tab[z][y][x] = data
return
end
tab[z][y] = {[x] = data}
return
end
tab[z] = {[y] = {[x] = data}}
end
function funcs.set_data_to_pos_optional(tab, z,y,x, data)
minetest.log("deprecated", "[vector_extras] set_data_to_pos_optional is " ..
"deprecated, use the minetest pos hash function instead.")
if vector.get_data_from_pos(tab, z,y,x) ~= nil then
return
end
funcs.set_data_to_pos(tab, z,y,x, data)
end
function funcs.remove_data_from_pos(tab, z,y,x)
minetest.log("deprecated", "[vector_extras] remove_data_from_pos is " ..
"deprecated, use the minetest pos hash function instead.")
if vector.get_data_from_pos(tab, z,y,x) == nil then
return
end
tab[z][y][x] = nil
if not next(tab[z][y]) then
tab[z][y] = nil
end
if not next(tab[z]) then
tab[z] = nil
end
end
function funcs.get_data_pos_table(tab)
minetest.log("deprecated", "[vector_extras] get_data_pos_table likely " ..
"is deprecated, use the minetest pos hash function instead.")
local t,n = {},1
local minz, miny, minx, maxz, maxy, maxx
for z,yxs in pairs(tab) do
if not minz then
minz = z
maxz = z
else
minz = math.min(minz, z)
maxz = math.max(maxz, z)
end
for y,xs in pairs(yxs) do
if not miny then
miny = y
maxy = y
else
miny = math.min(miny, y)
maxy = math.max(maxy, y)
end
for x,v in pairs(xs) do
if not minx then
minx = x
maxx = x
else
minx = math.min(minx, x)
maxx = math.max(maxx, x)
end
t[n] = {z,y,x, v}
n = n+1
end
end
end
return t, {x=minx, y=miny, z=minz}, {x=maxx, y=maxy, z=maxz}, n-1
end

1
mod.conf Normal file
View File

@ -0,0 +1 @@
name = vector_extras

View File

@ -1,183 +0,0 @@
vector.meta = vector.meta or {}
vector.meta.nodes = {}
vector.meta.nodes_file = {
load = function()
local nodesfile = io.open(minetest.get_worldpath()..'/vector_nodes.txt', "r")
if nodesfile then
local contents = nodesfile:read('*all')
io.close(nodesfile)
if contents ~= nil then
local lines = string.split(contents, "\n")
for _,entry in ipairs(lines) do
local name, px, py, pz, meta = unpack(string.split(entry, "°"))
vector.meta.set_node({x=px, y=py, z=pz}, name, meta)
end
end
end
end,
save = function() --WRITE CHANGES TO FILE
local output = ''
for x,ys in pairs(vector.meta.nodes) do
for y,zs in pairs(ys) do
for z,names in pairs(zs) do
for name,meta in pairs(names) do
output = name.."°"..x.."°"..y.."°"..z.."°"..dump(meta).."\n"
end
end
end
end
local f = io.open(minetest.get_worldpath()..'/vector_nodes.txt', "w")
f:write(output)
io.close(f)
end
}
local function table_empty(tab) --looks if it's an empty table
if next(tab) == nil then
return true
end
return false
end
function vector.meta.nodes_info() --returns an info string of the node table
local tmp = "[vector] "..dump(vector.meta.nodes).."\n[vector]:\n"
for x,a in pairs(vector.meta.nodes) do
for y,b in pairs(a) do
for z,c in pairs(b) do
for name,meta in pairs(c) do
tmp = tmp..">\t"..name.." "..x.." "..y.." "..z.." "..dump(meta).."\n"
end
end
end
end
return tmp
end
function vector.meta.clean_node_table() --replaces {} with nil
local again = true
while again do
again = false
for x,ys in pairs(vector.meta.nodes) do
if table_empty(ys) then
vector.meta.nodes[x] = nil
again = true
else
for y,zs in pairs(ys) do
if table_empty(zs) then
vector.meta.nodes[x][y] = nil
again = true
else
for z,names in pairs(zs) do
if table_empty(names) then
vector.meta.nodes[x][y][z] = nil
again = true
else
for name,meta in pairs(names) do
if table_empty(meta)
or meta == "" then
vector.meta.nodes[x][y][z][name] = nil
again = true
end
end
end
end
end
end
end
end
end
end
function vector.meta.complete_node_table(pos, name) --neccesary because tab[1] wouldn't work if tab is not a table
local tmp = vector.meta.nodes[pos.x]
if not tmp then
vector.meta.nodes[pos.x] = {}
end
local tmp = vector.meta.nodes[pos.x][pos.y]
if not tmp then
vector.meta.nodes[pos.x][pos.y] = {}
end
local tmp = vector.meta.nodes[pos.x][pos.y][pos.z]
if not tmp then
vector.meta.nodes[pos.x][pos.y][pos.z] = {}
end
local tmp = vector.meta.nodes[pos.x][pos.y][pos.z][name]
if not tmp then
vector.meta.nodes[pos.x][pos.y][pos.z][name] = {}
end
end
function vector.meta.get_node(pos, name)
if not pos then
return false
end
local tmp = vector.meta.nodes[pos.x]
if not tmp
or table_empty(tmp) then
return false
end
local tmp = vector.meta.nodes[pos.x][pos.y]
if not tmp
or table_empty(tmp) then
return false
end
local tmp = vector.meta.nodes[pos.x][pos.y][pos.z]
if not tmp
or table_empty(tmp) then
return false
end
-- if name isn't mentioned, just look if there's a node
if not name then
return true
end
local tmp = vector.meta.nodes[pos.x][pos.y][pos.z][name]
if not tmp
or table_empty(tmp) then
return false
end
return tmp
end
function vector.meta.remove_node(pos)
if not pos then
return false
end
if vector.meta.get_node(pos) then
vector.meta.nodes[pos.x][pos.y][pos.z] = nil
local xarr = vector.meta.nodes[pos.x]
if table_empty(xarr[pos.y]) then
vector.meta.nodes[pos.x][pos.y] = nil
end
if table_empty(xarr) then
vector.meta.nodes[pos.x] = nil
end
else
print("[vector_extras] Warning: The node at "..vector.pos_to_string(pos).." wasn't stored in vector.meta.nodes.")
end
end
function vector.meta.set_node(pos, name, meta)
if not (name or pos) then
return false
end
vector.meta.complete_node_table(pos, name)
meta = meta or true
vector.meta.nodes[pos.x][pos.y][pos.z][name] = meta
end
minetest.register_chatcommand('cleanvectormetatable',{
description = 'Tidy up it.',
params = "",
privs = {},
func = function(name)
vector.meta.clean_node_table()
local tmp = vector.meta.nodes_info()
minetest.chat_send_player(name, tmp)
print("[vector_extras] "..tmp)
end
})
vector.meta.nodes_file.load()