commit | author | age
|
b001a6
|
1 |
local S = technic.getter |
Z |
2 |
|
|
3 |
local desc = S("Administrative World Anchor") |
|
4 |
|
|
5 |
local function compute_forceload_positions(pos, meta) |
|
6 |
local radius = meta:get_int("radius") |
|
7 |
local minpos = vector.subtract(pos, vector.new(radius, radius, radius)) |
|
8 |
local maxpos = vector.add(pos, vector.new(radius, radius, radius)) |
|
9 |
local minbpos = {} |
|
10 |
local maxbpos = {} |
|
11 |
for _, coord in ipairs({"x","y","z"}) do |
|
12 |
minbpos[coord] = math.floor(minpos[coord] / 16) * 16 |
|
13 |
maxbpos[coord] = math.floor(maxpos[coord] / 16) * 16 |
|
14 |
end |
|
15 |
local flposes = {} |
|
16 |
for x = minbpos.x, maxbpos.x, 16 do |
|
17 |
for y = minbpos.y, maxbpos.y, 16 do |
|
18 |
for z = minbpos.z, maxbpos.z, 16 do |
|
19 |
table.insert(flposes, vector.new(x, y, z)) |
|
20 |
end |
|
21 |
end |
|
22 |
end |
|
23 |
return flposes |
|
24 |
end |
|
25 |
|
|
26 |
local function currently_forceloaded_positions(meta) |
|
27 |
local ser = meta:get_string("forceloaded") |
|
28 |
return ser == "" and {} or minetest.deserialize(ser) |
|
29 |
end |
|
30 |
|
|
31 |
local function forceload_off(meta) |
|
32 |
local flposes = currently_forceloaded_positions(meta) |
|
33 |
meta:set_string("forceloaded", "") |
|
34 |
for _, p in ipairs(flposes) do |
|
35 |
minetest.forceload_free_block(p) |
|
36 |
end |
|
37 |
end |
|
38 |
|
|
39 |
local function forceload_on(pos, meta) |
|
40 |
local want_flposes = compute_forceload_positions(pos, meta) |
|
41 |
local have_flposes = {} |
|
42 |
for _, p in ipairs(want_flposes) do |
|
43 |
if minetest.forceload_block(p) then |
|
44 |
table.insert(have_flposes, p) |
|
45 |
end |
|
46 |
end |
|
47 |
meta:set_string("forceloaded", #have_flposes == 0 and "" or minetest.serialize(have_flposes)) |
|
48 |
end |
|
49 |
|
|
50 |
local function set_display(pos, meta) |
0f6bdb
|
51 |
local ESC = minetest.formspec_escape |
b001a6
|
52 |
meta:set_string("infotext", S(meta:get_int("enabled") ~= 0 and "%s Enabled" or "%s Disabled"):format(desc)) |
Z |
53 |
meta:set_string("formspec", |
|
54 |
"size[5,3.5]".. |
|
55 |
"item_image[0,0;1,1;technic:admin_anchor]".. |
0f6bdb
|
56 |
"label[1,0;"..ESC(desc).."]".. |
S |
57 |
"label[0,1;"..ESC(S("Owner:").." "..meta:get_string("owner")).."]".. |
b001a6
|
58 |
(meta:get_int("locked") == 0 and |
0f6bdb
|
59 |
"button[3,1;2,1;lock;"..ESC(S("Unlocked")).."]" or |
S |
60 |
"button[3,1;2,1;unlock;"..ESC(S("Locked")).."]").. |
|
61 |
"field[0.25,2.3;1,1;radius;"..ESC(S("Radius:"))..";"..meta:get_int("radius").."]".. |
b001a6
|
62 |
(meta:get_int("enabled") == 0 and |
0f6bdb
|
63 |
"button[3,2;2,1;enable;"..ESC(S("Disabled")).."]" or |
S |
64 |
"button[3,2;2,1;disable;"..ESC(S("Enabled")).."]").. |
|
65 |
"label[0,3;"..ESC(S("Keeping %d/%d map blocks loaded"):format( |
|
66 |
#currently_forceloaded_positions(meta), #compute_forceload_positions(pos, meta) |
|
67 |
)).."]") |
b001a6
|
68 |
end |
Z |
69 |
|
|
70 |
minetest.register_node("technic:admin_anchor", { |
|
71 |
description = desc, |
|
72 |
drawtype = "normal", |
|
73 |
tiles = {"technic_admin_anchor.png"}, |
|
74 |
is_ground_content = true, |
772c21
|
75 |
groups = {cracky=3, not_in_creative_inventory=1}, |
b001a6
|
76 |
sounds = default.node_sound_stone_defaults(), |
Z |
77 |
after_place_node = function (pos, placer) |
|
78 |
local meta = minetest.get_meta(pos) |
|
79 |
if placer and placer:is_player() then |
|
80 |
meta:set_string("owner", placer:get_player_name()) |
|
81 |
end |
|
82 |
set_display(pos, meta) |
|
83 |
end, |
|
84 |
can_dig = function (pos, player) |
|
85 |
local meta = minetest.get_meta(pos) |
0f6bdb
|
86 |
return meta:get_int("locked") == 0 or |
S |
87 |
(player and player:is_player() and player:get_player_name() == meta:get_string("owner")) |
b001a6
|
88 |
end, |
Z |
89 |
on_destruct = function (pos) |
|
90 |
local meta = minetest.get_meta(pos) |
|
91 |
forceload_off(meta) |
|
92 |
end, |
|
93 |
on_receive_fields = function (pos, formname, fields, sender) |
|
94 |
local meta = minetest.get_meta(pos) |
|
95 |
if (meta:get_int("locked") ~= 0 or fields.lock) and |
|
96 |
not (sender and sender:is_player() and |
|
97 |
sender:get_player_name() == meta:get_string("owner")) then |
|
98 |
return |
|
99 |
end |
|
100 |
if fields.unlock then meta:set_int("locked", 0) end |
|
101 |
if fields.lock then meta:set_int("locked", 1) end |
|
102 |
if fields.disable or fields.enable or fields.radius then |
|
103 |
forceload_off(meta) |
|
104 |
if fields.disable then meta:set_int("enabled", 0) end |
|
105 |
if fields.enable then meta:set_int("enabled", 1) end |
0f6bdb
|
106 |
if fields.radius |
S |
107 |
and string.find(fields.radius, "^[0-9]+$") |
|
108 |
and tonumber(fields.radius) < 256 then |
|
109 |
meta:set_int("radius", fields.radius) |
|
110 |
end |
b001a6
|
111 |
if meta:get_int("enabled") ~= 0 then |
Z |
112 |
forceload_on(pos, meta) |
|
113 |
end |
|
114 |
end |
|
115 |
set_display(pos, meta) |
|
116 |
end, |
|
117 |
}) |