upgrade mover with movers farming in dig mode only, update keypad infotext when playing sounds, moving some code and various things...
306 lines
11 KiB
Lua
306 lines
11 KiB
Lua
-- ENVIRO block: change physics and skybox for players
|
|
-- Note: nonadmin players are limited in changes
|
|
|
|
-- rnd 2016:
|
|
|
|
local F, S = basic_machines.F, basic_machines.S
|
|
local max_range = basic_machines.properties.max_range
|
|
local use_player_monoids = minetest.global_exists("player_monoids")
|
|
local enviro_sky = {}
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
enviro_sky[player:get_player_name()] = nil
|
|
end)
|
|
|
|
if use_player_monoids then
|
|
-- Sneak monoid. Effect values are sneak booleans.
|
|
basic_machines.player_sneak = player_monoids.make_monoid({
|
|
combine = function(p, q) return p or q end,
|
|
fold = function(elems)
|
|
for _, v in pairs(elems) do
|
|
if not v then return false end
|
|
end
|
|
|
|
return true
|
|
end,
|
|
identity = true,
|
|
apply = function(can_sneak, player)
|
|
local ov = player:get_physics_override()
|
|
ov.sneak = can_sneak
|
|
player:set_physics_override(ov)
|
|
end
|
|
})
|
|
end
|
|
|
|
local space_textures = basic_machines.settings.space_textures
|
|
space_textures = space_textures ~= "" and space_textures:split() or {
|
|
"basic_machines_stars.png", "basic_machines_stars.png", "basic_machines_stars.png",
|
|
"basic_machines_stars.png", "basic_machines_stars.png", "basic_machines_stars.png"
|
|
}
|
|
local skyboxes = {
|
|
["-"] = {id = 1, type = "", tex = {}},
|
|
["surface"] = {id = 2, type = "regular", tex = {}},
|
|
["cave"] = {id = 3, type = "skybox", tex = {
|
|
"basic_machines_black.png", "basic_machines_black.png", "basic_machines_black.png",
|
|
"basic_machines_black.png", "basic_machines_black.png", "basic_machines_black.png"
|
|
}},
|
|
["space"] = {id = 4, type = "skybox", tex = space_textures}
|
|
}
|
|
local enviro_skylist_translated = -- translations of skyboxes keys
|
|
table.concat({F(S("-")), F(S("surface")), F(S("cave")), F(S("space"))}, ",")
|
|
|
|
local function enviro_update_form(meta)
|
|
local skybox = meta:get_string("skybox")
|
|
local function twodigits(f) return ("%.2f"):format(f) end
|
|
meta:set_string("formspec", "formspec_version[4]size[10.25,9.65]" ..
|
|
"field[0.25,0.5;1,0.8;x0;" .. F(S("Target")) .. ";" .. meta:get_int("x0") ..
|
|
"]field[1.5,0.5;1,0.8;y0;;" .. meta:get_int("y0") .. "]field[2.75,0.5;1,0.8;z0;;" .. meta:get_int("z0") ..
|
|
"]field[4,0.5;1,0.8;radius;" .. F(S("Radius")) .. ";" .. meta:get_int("radius") ..
|
|
"]field[0.25,1.75;1,0.8;speed;" .. F(S("Speed")) .. ";" .. twodigits(meta:get_float("speed")) ..
|
|
"]field[1.5,1.75;1,0.8;jump;" .. F(S("Jump")) .. ";" .. twodigits(meta:get_float("jump")) ..
|
|
"]field[2.75,1.75;1,0.8;gravity;" .. F(S("Gravity")) .. ";" .. twodigits(meta:get_float("gravity")) ..
|
|
"]field[4,1.75;1,0.8;sneak;" .. F(S("Sneak")) .. ";" .. meta:get_int("sneak") ..
|
|
"]label[0.25,2.8;" .. F(S("Sky")) ..
|
|
"]dropdown[0.25,3;1.75,0.8;skybox;" .. enviro_skylist_translated .. ";" ..
|
|
(skyboxes[skybox] and skyboxes[skybox].id or 1) ..
|
|
"]label[6.5,0.7;" .. F(S("Fuel")) .. "]list[context;fuel;6.5,0.9;1,1]" ..
|
|
"button_exit[8.38,0.5;1,0.8;OK;" .. F(S("OK")) ..
|
|
"]button[8.38,1.75;1,0.8;help;" .. F(S("help")) .. "]" ..
|
|
basic_machines.get_form_player_inventory(0.25, 4.5, 8, 4, 0.25) ..
|
|
"listring[context;fuel]" ..
|
|
"listring[current_player;main]")
|
|
end
|
|
|
|
local function format_num(num, specifier) return (specifier):format(num) end
|
|
|
|
local function toggle_visibility(player, b)
|
|
player:set_sun({visible = b, sunrise_visible = b})
|
|
player:set_moon({visible = b})
|
|
player:set_stars({visible = b})
|
|
end
|
|
|
|
-- environment changer
|
|
minetest.register_node("basic_machines:enviro", {
|
|
description = S("Environment Changer"),
|
|
groups = {cracky = 3},
|
|
tiles = {"basic_machines_enviro.png"},
|
|
drawtype = "allfaces",
|
|
paramtype = "light",
|
|
param1 = 1,
|
|
sounds = default.node_sound_wood_defaults(),
|
|
|
|
after_place_node = function(pos, placer)
|
|
if not placer then return end
|
|
|
|
local meta, name = minetest.get_meta(pos), placer:get_player_name()
|
|
meta:set_string("infotext", S("Right click to set it. Activate by signal."))
|
|
meta:set_string("owner", name)
|
|
|
|
if minetest.check_player_privs(name, "privs") then meta:set_int("admin", 1) end
|
|
|
|
meta:set_int("x0", 0); meta:set_int("y0", 0); meta:set_int("z0", 0) -- target
|
|
meta:set_int("radius", 5)
|
|
meta:set_float("speed", 1)
|
|
meta:set_float("jump", 1)
|
|
meta:set_float("gravity", 1)
|
|
meta:set_int("sneak", 1)
|
|
meta:set_string("skybox", "-")
|
|
|
|
meta:get_inventory():set_size("fuel", 1)
|
|
|
|
enviro_update_form(meta)
|
|
end,
|
|
|
|
can_dig = function(pos, player) -- don't dig if fuel is inside, cause it will be destroyed
|
|
local meta = minetest.get_meta(pos)
|
|
return meta:get_inventory():is_empty("fuel") and meta:get_string("owner") == player:get_player_name()
|
|
end,
|
|
|
|
on_receive_fields = function(pos, formname, fields, sender)
|
|
local name = sender:get_player_name()
|
|
if fields.OK then
|
|
if minetest.is_protected(pos, name) then return end
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("infotext", S("Right click to set it. Activate by signal."))
|
|
local privs = minetest.check_player_privs(name, "privs")
|
|
|
|
-- target
|
|
local x0 = tonumber(fields.x0) or 0
|
|
local y0 = tonumber(fields.y0) or 0
|
|
local z0 = tonumber(fields.z0) or 0
|
|
if not privs and (math.abs(x0) > max_range or math.abs(y0) > max_range or math.abs(z0) > max_range) then return end
|
|
meta:set_int("x0", x0); meta:set_int("y0", y0); meta:set_int("z0", z0)
|
|
|
|
-- radius
|
|
local radius = tonumber(fields.radius) or 5
|
|
if (radius < 0 or radius > max_range) and not privs then return end
|
|
meta:set_int("radius", radius)
|
|
|
|
-- speed
|
|
local speed = tonumber(fields.speed) or 1
|
|
if (speed < 0 or speed > 1.2) and not privs then return end
|
|
meta:set_float("speed", ("%.2f"):format(speed))
|
|
|
|
-- jump
|
|
local jump = tonumber(fields.jump) or 1
|
|
if (jump < 0 or jump > 2) and not privs then return end
|
|
meta:set_float("jump", ("%.2f"):format(jump))
|
|
|
|
-- gravity
|
|
local gravity = tonumber(fields.gravity) or 1
|
|
if (gravity < 0.1 or gravity > 40) and not privs then return end
|
|
meta:set_float("gravity", ("%.2f"):format(gravity))
|
|
|
|
-- sneak
|
|
local sneak = tonumber(fields.sneak) or 1
|
|
if sneak < 0 or sneak > 1 then return end
|
|
meta:set_int("sneak", tonumber(fields.sneak))
|
|
|
|
-- skybox
|
|
fields.skybox = fields.skybox or "-"
|
|
meta:set_string("skybox", fields.skybox:match("%)([%w_-]+)") or "-")
|
|
|
|
enviro_update_form(meta)
|
|
|
|
elseif fields.help then
|
|
minetest.show_formspec(name, "basic_machines:help_enviro",
|
|
"formspec_version[4]size[7.4,7.4]textarea[0,0.35;7.4,7.05;help;" .. F(S("Environment changer help")) .. ";" ..
|
|
F(S([[Values:
|
|
|
|
Target: Center position of the area to apply environment effects
|
|
x: [-@1, @2], y: [-@3, @4], z: [-@5, @6]
|
|
Radius: [0, @7]
|
|
Speed: [0, 1.2]
|
|
Jump: [0, 2]
|
|
Gravity: [0.1, 40]
|
|
Sneak: [0, 1]
|
|
Sky: -, surface, cave or space
|
|
]], max_range, max_range, max_range, max_range, max_range, max_range, max_range)) .. "]")
|
|
end
|
|
end,
|
|
|
|
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
|
if minetest.is_protected(pos, player:get_player_name()) then return 0 end
|
|
return stack:get_count()
|
|
end,
|
|
|
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
|
if minetest.is_protected(pos, player:get_player_name()) then return 0 end
|
|
return stack:get_count()
|
|
end,
|
|
|
|
effector = {
|
|
action_on = function(pos, _)
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
if meta:get_int("admin") ~= 1 then -- fuel needed for nonadmin
|
|
local inv, stack = meta:get_inventory(), ItemStack("default:diamond")
|
|
if inv:contains_item("fuel", stack) then
|
|
inv:remove_item("fuel", stack)
|
|
else
|
|
meta:set_string("infotext", S("Error. Insert diamond in fuel inventory.")); return
|
|
end
|
|
end
|
|
|
|
local radius, gravity, skybox = meta:get_int("radius"), meta:get_float("gravity"), meta:get_string("skybox")
|
|
if meta:contains("r") then -- for compatibility
|
|
local meta_new = meta:to_table(); meta:from_table(nil); local fields = meta_new.fields
|
|
fields.infotext = S("Right click to set it. Activate by signal.")
|
|
if minetest.check_player_privs(fields.owner, "privs") then fields.admin = 1 end
|
|
radius = tonumber(fields.r); fields.r, fields.radius = nil, radius
|
|
gravity = tonumber(fields.g); fields.g, fields.gravity = nil, gravity
|
|
skybox = "-"; fields.skybox = "-"; fields.public = nil
|
|
if minetest.get_meta(pos):from_table(meta_new) then meta = minetest.get_meta(pos) else return end
|
|
enviro_update_form(meta)
|
|
end
|
|
|
|
if radius <= 0 then return end
|
|
local physics = {
|
|
speed = meta:get_float("speed"),
|
|
jump = meta:get_float("jump"),
|
|
gravity = gravity,
|
|
sneak = meta:get_int("sneak")
|
|
}
|
|
|
|
meta:set_string("infotext", S("Settings: Speed=@1 Jump=@2 Gravity=@3 Sneak=@4 Sky=@5",
|
|
format_num(physics.speed, "%.2f"), format_num(physics.jump, "%.2f"),
|
|
format_num(physics.gravity, "%.2f"), physics.sneak, S(skybox)))
|
|
|
|
local pos0 = vector.add(pos,
|
|
{x = meta:get_int("x0"), y = meta:get_int("y0"), z = meta:get_int("z0")})
|
|
for _, player in ipairs(minetest.get_connected_players()) do
|
|
local pos1 = player:get_pos()
|
|
if math.sqrt((pos1.x - pos0.x)^2 + (pos1.y - pos0.y)^2 + (pos1.z - pos0.z)^2) <= radius then
|
|
physics.sneak = physics.sneak == 1
|
|
if use_player_monoids then
|
|
player_monoids.speed:add_change(player, physics.speed,
|
|
"basic_machines:physics")
|
|
player_monoids.jump:add_change(player, physics.jump,
|
|
"basic_machines:physics")
|
|
player_monoids.gravity:add_change(player, physics.gravity,
|
|
"basic_machines:physics")
|
|
basic_machines.player_sneak:add_change(player, physics.sneak,
|
|
"basic_machines:physics")
|
|
else
|
|
player:set_physics_override(physics)
|
|
end
|
|
|
|
if skybox ~= "-" then
|
|
local sky = skyboxes[skybox]
|
|
local b = skybox == "surface"
|
|
player:set_sky({base_color = 0x000000, type = sky["type"], textures = sky["tex"], clouds = b})
|
|
toggle_visibility(player, b)
|
|
enviro_sky[player:get_player_name()] = skybox
|
|
end
|
|
end
|
|
end
|
|
|
|
-- attempt to set acceleration to balls, if any around
|
|
for _, obj in ipairs(minetest.get_objects_inside_radius(pos0, radius)) do
|
|
local lua_entity = obj:get_luaentity()
|
|
if lua_entity and lua_entity.name == "basic_machines:ball" then
|
|
obj:set_acceleration({x = 0, y = -physics.gravity, z = 0})
|
|
end
|
|
end
|
|
end
|
|
}
|
|
})
|
|
|
|
-- DEFAULT (SPAWN) PHYSICS VALUE/SKYBOX
|
|
local function reset_player_physics(player)
|
|
if player and player:is_player() then
|
|
if use_player_monoids then
|
|
player_monoids.speed:del_change(player, "basic_machines:physics")
|
|
player_monoids.jump:del_change(player, "basic_machines:physics")
|
|
player_monoids.gravity:del_change(player, "basic_machines:physics")
|
|
basic_machines.player_sneak:del_change(player, "basic_machines:physics")
|
|
else
|
|
player:set_physics_override({speed = 1, jump = 1, gravity = 1, sneak = true})
|
|
end
|
|
|
|
local name = player:get_player_name()
|
|
|
|
if enviro_sky[name] and enviro_sky[name] ~= "surface" then -- default skybox is "surface"
|
|
local sky = skyboxes["surface"]
|
|
player:set_sky({type = sky["type"], textures = sky["tex"], clouds = true})
|
|
toggle_visibility(player, true)
|
|
enviro_sky[name] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
-- restore default physics values on respawn of player
|
|
minetest.register_on_respawnplayer(reset_player_physics)
|
|
|
|
if basic_machines.settings.register_crafts then
|
|
-- RECIPE: extremely expensive
|
|
minetest.register_craft({
|
|
output = "basic_machines:enviro",
|
|
recipe = {
|
|
{"basic_machines:generator", "basic_machines:clockgen", "basic_machines:generator"},
|
|
{"basic_machines:generator", "basic_machines:generator", "basic_machines:generator"},
|
|
{"basic_machines:generator", "basic_machines:generator", "basic_machines:generator"}
|
|
}
|
|
})
|
|
end |