Administrative world anchor
This commit is contained in:
parent
38e85e9775
commit
b001a67979
56
manual.md
56
manual.md
@ -725,6 +725,62 @@ the electrical system which is 100% efficient in moving energy around.
|
|||||||
To transfer more than 10000 EU/s between networks, connect multiple
|
To transfer more than 10000 EU/s between networks, connect multiple
|
||||||
supply converters in parallel.
|
supply converters in parallel.
|
||||||
|
|
||||||
|
administrative world anchor
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
A world anchor is an object in the Minetest world that causes the server
|
||||||
|
to keep surrounding parts of the world running even when no players
|
||||||
|
are nearby. It is mainly used to allow machines to run unattended:
|
||||||
|
normally machines are suspended when not near a player. The technic
|
||||||
|
mod supplies a form of world anchor, as a placable block, but it is not
|
||||||
|
straightforwardly available to players. There is no recipe for it, so it
|
||||||
|
is only available if explicitly spawned into existence by someone with
|
||||||
|
administrative privileges. In a single-player world, the single player
|
||||||
|
normally has administrative privileges, and can obtain a world anchor
|
||||||
|
by entering the chat command "/give singleplayer technic:admin\_anchor".
|
||||||
|
|
||||||
|
The world anchor tries to force a cubical area, centred upon the anchor,
|
||||||
|
to stay loaded. The distance from the anchor to the most distant map
|
||||||
|
nodes that it will keep loaded is referred to as the "radius", and can be
|
||||||
|
set in the world anchor's interaction form. The radius can be set as low
|
||||||
|
as 0, meaning that the anchor only tries to keep itself loaded, or as high
|
||||||
|
as 255, meaning that it will operate on a 511×511×511 cube.
|
||||||
|
Larger radii are forbidden, to avoid typos causing the server excessive
|
||||||
|
work; to keep a larger area loaded, use multiple anchors. Also use
|
||||||
|
multiple anchors if the area to be kept loaded is not well approximated
|
||||||
|
by a cube.
|
||||||
|
|
||||||
|
The world is always kept loaded in units of 16×16×16 cubes,
|
||||||
|
confusingly known as "map blocks". The anchor's configured radius takes
|
||||||
|
no account of map block boundaries, but the anchor's effect is actually to
|
||||||
|
keep loaded each map block that contains any part of the configured cube.
|
||||||
|
The anchor's interaction form includes a status note showing how many map
|
||||||
|
blocks this is, and how many of those it is successfully keeping loaded.
|
||||||
|
When the anchor is disabled, as it is upon placement, it will always
|
||||||
|
show that it is keeping no map blocks loaded; this does not indicate
|
||||||
|
any kind of failure.
|
||||||
|
|
||||||
|
The world anchor can optionally be locked. When it is locked, only
|
||||||
|
the anchor's owner, the player who placed it, can reconfigure it or
|
||||||
|
remove it. Only the owner can lock it. Locking an anchor is useful
|
||||||
|
if the use of anchors is being tightly controlled by administrators:
|
||||||
|
an administrator can set up a locked anchor and be sure that it will
|
||||||
|
not be set by ordinary players to an unapproved configuration.
|
||||||
|
|
||||||
|
The server limits the ability of world anchors to keep parts of the world
|
||||||
|
loaded, to avoid overloading the server. The total number of map blocks
|
||||||
|
that can be kept loaded in this way is set by the server configuration
|
||||||
|
item "max\_forceloaded\_blocks" (in minetest.conf), which defaults to
|
||||||
|
only 16. For comparison, each player normally keeps 125 map blocks loaded
|
||||||
|
(a radius of 32). If an enabled world anchor shows that it is failing to
|
||||||
|
keep all the map blocks loaded that it would like to, this can be fixed
|
||||||
|
by increasing max\_forceloaded\_blocks by the amount of the shortfall.
|
||||||
|
|
||||||
|
The tight limit on force-loading is the reason why the world anchor is
|
||||||
|
not directly available to players. With the limit so low both by default
|
||||||
|
and in common practice, the only feasible way to determine where world
|
||||||
|
anchors should be used is for administrators to decide it directly.
|
||||||
|
|
||||||
subjects missing from this manual
|
subjects missing from this manual
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
|
@ -54,6 +54,12 @@ Out: = Raus:
|
|||||||
Slot %d = Fach %d
|
Slot %d = Fach %d
|
||||||
Itemwise = Einzelstuecke
|
Itemwise = Einzelstuecke
|
||||||
Stackwise = Ganzer Stapel
|
Stackwise = Ganzer Stapel
|
||||||
|
Owner: =
|
||||||
|
Unlocked =
|
||||||
|
Locked =
|
||||||
|
Radius: =
|
||||||
|
Enabled =
|
||||||
|
Disabled =
|
||||||
|
|
||||||
## Machine names
|
## Machine names
|
||||||
# $1: Tier
|
# $1: Tier
|
||||||
@ -92,6 +98,7 @@ Fuel-Fired Furnace = Kohle-Ofen
|
|||||||
Wind Mill Frame = Windmuehlengeruest
|
Wind Mill Frame = Windmuehlengeruest
|
||||||
Forcefield = Kraftfeld
|
Forcefield = Kraftfeld
|
||||||
Nuclear Reactor Rod Compartment = Brennstabfaecher
|
Nuclear Reactor Rod Compartment = Brennstabfaecher
|
||||||
|
Administrative World Anchor =
|
||||||
|
|
||||||
## Machine-specific
|
## Machine-specific
|
||||||
# $1: Pruduced EU
|
# $1: Pruduced EU
|
||||||
@ -106,6 +113,7 @@ Production at %d%% = Produktion bei %d%%
|
|||||||
Choose Milling Program: = Waehle ein Fraesprogramm:
|
Choose Milling Program: = Waehle ein Fraesprogramm:
|
||||||
Slim Elements half / normal height: = Schmale Elemente von halber / normaler Hoehe:
|
Slim Elements half / normal height: = Schmale Elemente von halber / normaler Hoehe:
|
||||||
Current track %s = Aktueller Titel %s
|
Current track %s = Aktueller Titel %s
|
||||||
|
Keeping %d/%d map blocks loaded =
|
||||||
|
|
||||||
## CNC
|
## CNC
|
||||||
Cylinder = Zylinder
|
Cylinder = Zylinder
|
||||||
|
@ -50,6 +50,12 @@ Range = Alcance
|
|||||||
Enable/Disable = Habilitar/Deshabilitar
|
Enable/Disable = Habilitar/Deshabilitar
|
||||||
Itemwise =
|
Itemwise =
|
||||||
Stackwise =
|
Stackwise =
|
||||||
|
Owner: =
|
||||||
|
Unlocked =
|
||||||
|
Locked =
|
||||||
|
Radius: =
|
||||||
|
Enabled =
|
||||||
|
Disabled =
|
||||||
|
|
||||||
## Machine names
|
## Machine names
|
||||||
# $1: Tier
|
# $1: Tier
|
||||||
@ -88,6 +94,7 @@ Fuel-Fired Furnace = Horno a Carbon
|
|||||||
Forcefield = Campo de Fuerza
|
Forcefield = Campo de Fuerza
|
||||||
Nuclear Reactor Rod Compartment = Compartimiento para Vara de Reactor Nuclear
|
Nuclear Reactor Rod Compartment = Compartimiento para Vara de Reactor Nuclear
|
||||||
Wind Mill Frame = Armazon de Molino de Viento
|
Wind Mill Frame = Armazon de Molino de Viento
|
||||||
|
Administrative World Anchor =
|
||||||
|
|
||||||
## Machine-specific
|
## Machine-specific
|
||||||
# $1: Pruduced EU
|
# $1: Pruduced EU
|
||||||
@ -100,6 +107,7 @@ Power level = Nivel de Poder
|
|||||||
%s. Supply: %d Demand: %d = %s. Alimentacion: %d Demanda: %d
|
%s. Supply: %d Demand: %d = %s. Alimentacion: %d Demanda: %d
|
||||||
# $1: Production percent
|
# $1: Production percent
|
||||||
Production at %d%% = Produccion en %d%%
|
Production at %d%% = Produccion en %d%%
|
||||||
|
Keeping %d/%d map blocks loaded =
|
||||||
|
|
||||||
## CNC Machine
|
## CNC Machine
|
||||||
Element Edge = Elemento Borde
|
Element Edge = Elemento Borde
|
||||||
|
@ -51,6 +51,12 @@ Out: = Uscita:
|
|||||||
Slot %d =
|
Slot %d =
|
||||||
Itemwise = Singolo elemento
|
Itemwise = Singolo elemento
|
||||||
Stackwise = pila completa
|
Stackwise = pila completa
|
||||||
|
Owner: =
|
||||||
|
Unlocked =
|
||||||
|
Locked =
|
||||||
|
Radius: =
|
||||||
|
Enabled =
|
||||||
|
Disabled =
|
||||||
|
|
||||||
## Machine names
|
## Machine names
|
||||||
# $1: Tier
|
# $1: Tier
|
||||||
@ -89,6 +95,7 @@ Fuel-Fired Furnace = Fornace a carbone
|
|||||||
Wind Mill Frame = Pala eolica
|
Wind Mill Frame = Pala eolica
|
||||||
Forcefield = Campo di forza
|
Forcefield = Campo di forza
|
||||||
Nuclear Reactor Rod Compartment = Compartimento combustibile nucleare
|
Nuclear Reactor Rod Compartment = Compartimento combustibile nucleare
|
||||||
|
Administrative World Anchor =
|
||||||
|
|
||||||
## Machine-specific
|
## Machine-specific
|
||||||
# $1: Pruduced EU
|
# $1: Pruduced EU
|
||||||
@ -103,6 +110,7 @@ Production at %d%% = Produzione a %d%%
|
|||||||
Choose Milling Program: = Scegliere un programma di Fresatura
|
Choose Milling Program: = Scegliere un programma di Fresatura
|
||||||
Slim Elements half / normal height: = Metà elementi sottili / altezza normale:
|
Slim Elements half / normal height: = Metà elementi sottili / altezza normale:
|
||||||
Current track %s = Traccia corrente %s
|
Current track %s = Traccia corrente %s
|
||||||
|
Keeping %d/%d map blocks loaded =
|
||||||
|
|
||||||
## CNC
|
## CNC
|
||||||
Cylinder = Cilindro
|
Cylinder = Cilindro
|
||||||
|
@ -58,6 +58,12 @@ Itemwise =
|
|||||||
Stackwise =
|
Stackwise =
|
||||||
Ignoring Mesecon Signal =
|
Ignoring Mesecon Signal =
|
||||||
Controlled by Mesecon Signal =
|
Controlled by Mesecon Signal =
|
||||||
|
Owner: =
|
||||||
|
Unlocked =
|
||||||
|
Locked =
|
||||||
|
Radius: =
|
||||||
|
Enabled =
|
||||||
|
Disabled =
|
||||||
|
|
||||||
## Machine names
|
## Machine names
|
||||||
# $1: Tier
|
# $1: Tier
|
||||||
@ -97,6 +103,7 @@ Fuel-Fired Furnace =
|
|||||||
Wind Mill Frame =
|
Wind Mill Frame =
|
||||||
Forcefield =
|
Forcefield =
|
||||||
Nuclear Reactor Rod Compartment =
|
Nuclear Reactor Rod Compartment =
|
||||||
|
Administrative World Anchor =
|
||||||
|
|
||||||
## Machine-specific
|
## Machine-specific
|
||||||
# $1: Pruduced EU
|
# $1: Pruduced EU
|
||||||
@ -111,6 +118,7 @@ Production at %d%% =
|
|||||||
Choose Milling Program: =
|
Choose Milling Program: =
|
||||||
Slim Elements half / normal height: =
|
Slim Elements half / normal height: =
|
||||||
Current track %s =
|
Current track %s =
|
||||||
|
Keeping %d/%d map blocks loaded =
|
||||||
|
|
||||||
## CNC
|
## CNC
|
||||||
Cylinder =
|
Cylinder =
|
||||||
|
109
technic/machines/other/anchor.lua
Normal file
109
technic/machines/other/anchor.lua
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
local S = technic.getter
|
||||||
|
|
||||||
|
local desc = S("Administrative World Anchor")
|
||||||
|
|
||||||
|
local function compute_forceload_positions(pos, meta)
|
||||||
|
local radius = meta:get_int("radius")
|
||||||
|
local minpos = vector.subtract(pos, vector.new(radius, radius, radius))
|
||||||
|
local maxpos = vector.add(pos, vector.new(radius, radius, radius))
|
||||||
|
local minbpos = {}
|
||||||
|
local maxbpos = {}
|
||||||
|
for _, coord in ipairs({"x","y","z"}) do
|
||||||
|
minbpos[coord] = math.floor(minpos[coord] / 16) * 16
|
||||||
|
maxbpos[coord] = math.floor(maxpos[coord] / 16) * 16
|
||||||
|
end
|
||||||
|
local flposes = {}
|
||||||
|
for x = minbpos.x, maxbpos.x, 16 do
|
||||||
|
for y = minbpos.y, maxbpos.y, 16 do
|
||||||
|
for z = minbpos.z, maxbpos.z, 16 do
|
||||||
|
table.insert(flposes, vector.new(x, y, z))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return flposes
|
||||||
|
end
|
||||||
|
|
||||||
|
local function currently_forceloaded_positions(meta)
|
||||||
|
local ser = meta:get_string("forceloaded")
|
||||||
|
return ser == "" and {} or minetest.deserialize(ser)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function forceload_off(meta)
|
||||||
|
local flposes = currently_forceloaded_positions(meta)
|
||||||
|
meta:set_string("forceloaded", "")
|
||||||
|
for _, p in ipairs(flposes) do
|
||||||
|
minetest.forceload_free_block(p)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function forceload_on(pos, meta)
|
||||||
|
local want_flposes = compute_forceload_positions(pos, meta)
|
||||||
|
local have_flposes = {}
|
||||||
|
for _, p in ipairs(want_flposes) do
|
||||||
|
if minetest.forceload_block(p) then
|
||||||
|
table.insert(have_flposes, p)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
meta:set_string("forceloaded", #have_flposes == 0 and "" or minetest.serialize(have_flposes))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set_display(pos, meta)
|
||||||
|
meta:set_string("infotext", S(meta:get_int("enabled") ~= 0 and "%s Enabled" or "%s Disabled"):format(desc))
|
||||||
|
meta:set_string("formspec",
|
||||||
|
"size[5,3.5]"..
|
||||||
|
"item_image[0,0;1,1;technic:admin_anchor]"..
|
||||||
|
"label[1,0;"..minetest.formspec_escape(desc).."]"..
|
||||||
|
"label[0,1;"..minetest.formspec_escape(S("Owner:").." "..meta:get_string("owner")).."]"..
|
||||||
|
(meta:get_int("locked") == 0 and
|
||||||
|
"button[3,1;2,1;lock;"..minetest.formspec_escape(S("Unlocked")).."]" or
|
||||||
|
"button[3,1;2,1;unlock;"..minetest.formspec_escape(S("Locked")).."]")..
|
||||||
|
"field[0.25,2.3;1,1;radius;"..minetest.formspec_escape(S("Radius:"))..";"..meta:get_int("radius").."]"..
|
||||||
|
(meta:get_int("enabled") == 0 and
|
||||||
|
"button[3,2;2,1;enable;"..minetest.formspec_escape(S("Disabled")).."]" or
|
||||||
|
"button[3,2;2,1;disable;"..minetest.formspec_escape(S("Enabled")).."]")..
|
||||||
|
"label[0,3;"..minetest.formspec_escape(S("Keeping %d/%d map blocks loaded"):format(#currently_forceloaded_positions(meta), #compute_forceload_positions(pos, meta))).."]")
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_node("technic:admin_anchor", {
|
||||||
|
description = desc,
|
||||||
|
drawtype = "normal",
|
||||||
|
tiles = {"technic_admin_anchor.png"},
|
||||||
|
is_ground_content = true,
|
||||||
|
groups = {cracky=3},
|
||||||
|
sounds = default.node_sound_stone_defaults(),
|
||||||
|
after_place_node = function (pos, placer)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if placer and placer:is_player() then
|
||||||
|
meta:set_string("owner", placer:get_player_name())
|
||||||
|
end
|
||||||
|
set_display(pos, meta)
|
||||||
|
end,
|
||||||
|
can_dig = function (pos, player)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
return meta:get_int("locked") == 0 or (player and player:is_player() and player:get_player_name() == meta:get_string("owner"))
|
||||||
|
end,
|
||||||
|
on_destruct = function (pos)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
forceload_off(meta)
|
||||||
|
end,
|
||||||
|
on_receive_fields = function (pos, formname, fields, sender)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if (meta:get_int("locked") ~= 0 or fields.lock) and
|
||||||
|
not (sender and sender:is_player() and
|
||||||
|
sender:get_player_name() == meta:get_string("owner")) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if fields.unlock then meta:set_int("locked", 0) end
|
||||||
|
if fields.lock then meta:set_int("locked", 1) end
|
||||||
|
if fields.disable or fields.enable or fields.radius then
|
||||||
|
forceload_off(meta)
|
||||||
|
if fields.disable then meta:set_int("enabled", 0) end
|
||||||
|
if fields.enable then meta:set_int("enabled", 1) end
|
||||||
|
if fields.radius and string.find(fields.radius, "^[0-9]+$") and tonumber(fields.radius) < 256 then meta:set_int("radius", fields.radius) end
|
||||||
|
if meta:get_int("enabled") ~= 0 then
|
||||||
|
forceload_on(pos, meta)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
set_display(pos, meta)
|
||||||
|
end,
|
||||||
|
})
|
@ -6,3 +6,4 @@ dofile(path.."/constructor.lua")
|
|||||||
if minetest.get_modpath("mesecons_mvps") ~= nil then
|
if minetest.get_modpath("mesecons_mvps") ~= nil then
|
||||||
dofile(path.."/frames.lua")
|
dofile(path.."/frames.lua")
|
||||||
end
|
end
|
||||||
|
dofile(path.."/anchor.lua")
|
||||||
|
BIN
technic/textures/technic_admin_anchor.png
Normal file
BIN
technic/textures/technic_admin_anchor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 873 B |
Loading…
Reference in New Issue
Block a user