203 lines
6.9 KiB
Lua
203 lines
6.9 KiB
Lua
-- (c) 2015-2016 rnd
|
|
-- Copyright (C) 2022-2025 мтест
|
|
-- See README.md for license details
|
|
|
|
local S = basic_machines.S
|
|
local exclusion_height = basic_machines.settings.exclusion_height
|
|
local space_effects = basic_machines.settings.space_effects
|
|
local space_start = basic_machines.settings.space_start
|
|
local space_start_eff = basic_machines.settings.space_start_eff
|
|
local use_player_monoids = minetest.global_exists("player_monoids")
|
|
local use_basic_protect = minetest.global_exists("basic_protect")
|
|
|
|
minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities)
|
|
if player:get_pos().y > space_start and hitter and hitter:is_player() then
|
|
if time_from_last_punch > 0.8 and vector.length(player:get_velocity()) > 0.2 then
|
|
local dir = vector.subtract(player:get_pos(), hitter:get_pos())
|
|
local unit_vector = vector.divide(dir, vector.length(dir))
|
|
local punch_vector = {x = 5, y = 0.9, z = 5}
|
|
player:add_velocity(vector.multiply(unit_vector, punch_vector)) -- push player a little
|
|
end
|
|
if tool_capabilities and ((tool_capabilities.damage_groups or {}).fleshy or 0) == 1 then
|
|
return true
|
|
end
|
|
end
|
|
end)
|
|
|
|
minetest.register_privilege("include", {
|
|
description = S("Allow player to move in exclusion zone")
|
|
})
|
|
|
|
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 = {
|
|
["surface"] = {type = "regular", tex = {}},
|
|
["space"] = {type = "skybox", tex = space_textures}
|
|
}
|
|
|
|
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
|
|
|
|
local function adjust_enviro(inspace, player) -- adjust players physics/skybox
|
|
if inspace == 1 then -- is player in space or not ?
|
|
local physics = {speed = 1, jump = 0.5, gravity = 0.1} -- value set for extreme test space spawn
|
|
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")
|
|
else
|
|
player:set_physics_override(physics)
|
|
end
|
|
|
|
local sky = skyboxes["space"]
|
|
player:set_sky({base_color = 0x000000, type = sky["type"], textures = sky["tex"], clouds = false})
|
|
toggle_visibility(player, false)
|
|
else
|
|
local physics = {speed = 1, jump = 1, gravity = 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")
|
|
else
|
|
player:set_physics_override(physics)
|
|
end
|
|
|
|
local sky = skyboxes["surface"]
|
|
player:set_sky({type = sky["type"], textures = sky["tex"], clouds = true})
|
|
toggle_visibility(player, true)
|
|
end
|
|
|
|
return inspace
|
|
end
|
|
|
|
local space = {}
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
space[player:get_player_name()] = nil
|
|
end)
|
|
|
|
local stimer = 0
|
|
local function pos_to_string(pos) return ("%s, %s, %s"):format(pos.x, pos.y, pos.z) end
|
|
local round, random = math.floor, math.random
|
|
|
|
local function protector_position(pos)
|
|
local r = 20; local ry = 2 * r
|
|
return {x = round(pos.x / r + 0.5) * r,
|
|
y = round(pos.y / ry + 0.5) * ry,
|
|
z = round(pos.z / r + 0.5) * r}
|
|
end
|
|
|
|
minetest.register_globalstep(function(dtime)
|
|
stimer = stimer + dtime; if stimer < 5 then return end; stimer = 0
|
|
|
|
for _, player in ipairs(minetest.get_connected_players()) do
|
|
local pos = player:get_pos()
|
|
local name = player:get_player_name()
|
|
local inspace
|
|
|
|
if pos.y > space_start then
|
|
inspace = 1
|
|
if pos.y > exclusion_height and not minetest.check_player_privs(name, "include") then
|
|
local spawn_pos = {
|
|
x = random(0, 100) * (random(2) == 1 and 1 or -1),
|
|
y = 1,
|
|
z = random(0, 100) * (random(2) == 1 and 1 or -1)
|
|
}
|
|
local spos = pos_to_string(vector.round(pos))
|
|
minetest.chat_send_player(name, S("Exclusion zone alert, current position: @1. Teleporting to @2.",
|
|
spos, pos_to_string(spawn_pos)))
|
|
minetest.log("action", "Exclusion zone alert: " .. name .. " at " .. spos)
|
|
if player.add_pos then -- for Minetest 5.9.0+
|
|
player:add_pos(vector.subtract(spawn_pos, pos))
|
|
else
|
|
player:set_pos(spawn_pos)
|
|
end
|
|
end
|
|
else
|
|
inspace = 0
|
|
end
|
|
|
|
-- only adjust player environment ONLY if change occurred (earth->space or space->earth!)
|
|
if inspace ~= space[name] then
|
|
space[name] = adjust_enviro(inspace, player)
|
|
end
|
|
|
|
if space_effects and inspace == 1 then -- special space code
|
|
local hp = player:get_hp()
|
|
if hp > 0 and not minetest.check_player_privs(name, "kick") then
|
|
if pos.y < space_start_eff and pos.y > space_start_eff - 380 then
|
|
minetest.chat_send_player(name, S("WARNING: you entered DEADLY RADIATION ZONE")); player:set_hp(hp - 15)
|
|
elseif use_basic_protect then
|
|
local ppos = protector_position(pos)
|
|
local populated = minetest.get_node(ppos).name == "basic_protect:protector"
|
|
if populated then
|
|
if minetest.get_meta(ppos):get_int("space") == 1 then populated = false end
|
|
end
|
|
if not populated then -- do damage if player found not close to protectors
|
|
player:set_hp(hp - 10) -- dead in 20/10 = 2 events
|
|
minetest.chat_send_player(name, S("WARNING: in space you must stay close to protected areas"))
|
|
end
|
|
elseif not minetest.is_protected(pos, "") then
|
|
player:set_hp(hp - 10) -- dead in 20/10 = 2 events
|
|
minetest.chat_send_player(name, S("WARNING: in space you must stay close to protected areas"))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
--[[
|
|
-- AIR EXPERIMENT
|
|
if basic_machines.use_default then
|
|
minetest.register_node("basic_machines:air", {
|
|
description = S("Enable breathing in space"),
|
|
groups = {not_in_creative_inventory = 1},
|
|
drawtype = "glasslike", -- drawtype = "liquid",
|
|
tiles = {"default_water_source_animated.png"},
|
|
use_texture_alpha = "blend",
|
|
paramtype = "light",
|
|
sunlight_propagates = true, -- Sunlight shines through
|
|
walkable = false, -- Would make the player collide with the air node
|
|
pointable = false, -- You can't select the node
|
|
diggable = false, -- You can't dig the node
|
|
buildable_to = true,
|
|
drop = "",
|
|
|
|
after_place_node = function(pos)
|
|
local r = 3
|
|
for i = -r, r do
|
|
for j = -r, r do
|
|
for k = -r, r do
|
|
local p = {x = pos.x + i, y = pos.y + j, z = pos.z + k}
|
|
if minetest.get_node(p).name == "air" then
|
|
minetest.set_node(p, {name = "basic_machines:air"})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
})
|
|
|
|
minetest.register_abm({
|
|
label = "[basic_machines] Air experiment",
|
|
nodenames = {"basic_machines:air"},
|
|
neighbors = {"air"},
|
|
interval = 10,
|
|
chance = 1,
|
|
action = function(pos)
|
|
minetest.remove_node(pos)
|
|
end
|
|
})
|
|
end
|
|
--]] |