forked from VoxeLibre/VoxeLibre
Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
kay27 | 6fa960ae26 |
|
@ -177,7 +177,5 @@ minetest.register_on_joinplayer(function(player)
|
|||
return_fields(player, "enchanting_lapis")
|
||||
end)
|
||||
|
||||
if minetest.is_creative_enabled("") then
|
||||
dofile(minetest.get_modpath(minetest.get_current_modname()).."/creative.lua")
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name = mcl_inventory
|
||||
author = BlockMen
|
||||
description = Adds the player inventory and creative inventory.
|
||||
depends = mcl_init, mcl_formspec, mcl_enchanting
|
||||
depends = mcl_init, mcl_formspec, mcl_enchanting, mcl_commands
|
||||
optional_depends = mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide, mcl_player
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
local gamemode_ids = {
|
||||
survival = 1,
|
||||
creative = 2,
|
||||
}
|
||||
|
||||
local id_to_gamemode = {}
|
||||
for gamemode, id in pairs(gamemode_ids) do
|
||||
id_to_gamemode[id] = gamemode
|
||||
end
|
||||
|
||||
local creative_mode = 'creative'
|
||||
|
||||
local storage = minetest.get_mod_storage()
|
||||
|
||||
local player_to_gamemode_id = minetest.deserialize(storage:get_string("player_to_gamemode_id") or "return {}") or {}
|
||||
minetest.register_on_shutdown(function()
|
||||
storage:set_string("player_to_gamemode_id", minetest.serialize(player_to_gamemode_id))
|
||||
end)
|
||||
|
||||
local core_is_creative_enabled = minetest.is_creative_enabled
|
||||
|
||||
minetest.is_creative_enabled = function(name)
|
||||
local id = player_to_gamemode_id[name]
|
||||
if id then
|
||||
local gamemode = id_to_gamemode[id]
|
||||
if gamemode then
|
||||
return gamemode == creative_mode
|
||||
end
|
||||
end
|
||||
return core_is_creative_enabled(name)
|
||||
end
|
||||
|
||||
local function handle_gamemode_command(player_name, new_gamemode)
|
||||
player_to_gamemode_id[player_name] = gamemode_ids[new_gamemode]
|
||||
return true
|
||||
end
|
||||
|
||||
if minetest.registered_chatcommands["gamemode"] then
|
||||
minetest.unregister_chatcommand("gamemode")
|
||||
end
|
||||
|
||||
local function get_gamemode_param()
|
||||
local param
|
||||
local i = 0
|
||||
for gamemode, _ in pairs(gamemode_ids) do
|
||||
if i == 0 then
|
||||
param = "("
|
||||
else
|
||||
param = param .. " | "
|
||||
end
|
||||
i = i + 1
|
||||
param = param .. gamemode
|
||||
end
|
||||
if i > 0 then
|
||||
param = param .. ") "
|
||||
end
|
||||
return param
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("gamemode", {
|
||||
params = S("@1[<name>]", get_gamemode_param()),
|
||||
description = S("Set game mode for player or yourself"),
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
if (param == "") then
|
||||
return false, S("Error: No game mode specified.")
|
||||
end
|
||||
if (gamemode_ids[param]) then
|
||||
handle_gamemode_command(name, param)
|
||||
else
|
||||
local new_gamemode, player_name = string.match(param, "^([%a]+) ([%a%d_-]+)$")
|
||||
if not new_gamemode or not gamemode_ids[new_gamemode] or not player_name then
|
||||
return false, S("Invalid usage, see /help @1", "gamemode")
|
||||
end
|
||||
handle_gamemode_command(player_name, new_gamemode)
|
||||
end
|
||||
end
|
||||
})
|
|
@ -1,5 +1,6 @@
|
|||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
dofile(modpath.."/gamemode.lua")
|
||||
dofile(modpath.."/kill.lua")
|
||||
dofile(modpath.."/setblock.lua")
|
||||
dofile(modpath.."/seed.lua")
|
||||
|
|
|
@ -10,7 +10,7 @@ Kill player or yourself=Spieler oder sich selbst töten
|
|||
Can use /say=Kann „/say“ benutzen
|
||||
<message>=<Nachricht>
|
||||
Send a message to every player=Nachricht an alle Spieler senden
|
||||
Invalid usage, see /help say.=Falsche Benutzung, siehe „/help say“.
|
||||
Invalid usage, see /help @1.=Falsche Benutzung, siehe „/help @1“.
|
||||
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <Node-Bezeichner>
|
||||
Set node at given position=Node (Block) an der gegebenen Position platzieren
|
||||
Invalid node=Unültiger Node
|
||||
|
@ -21,3 +21,6 @@ Ban list: @1=Bannliste: @1
|
|||
Show who is logged on=Anzeigen, wer eingeloggt ist
|
||||
Displays the world seed=Den Seed der Welt anzeigen
|
||||
Only peaceful mobs allowed!=Nur friedliche Mobs erlaubt!
|
||||
@1[<name>]=
|
||||
Set game mode for player or yourself=
|
||||
Error: No game mode specified.=
|
||||
|
|
|
@ -21,3 +21,6 @@ Ban list: @1=Lista de baneados: @1
|
|||
Show who is logged on=Mostrar quién ha iniciado sesión
|
||||
Displays the world seed=Muestra la semilla del mundo
|
||||
Only peaceful mobs allowed!=¡Solo se permiten animales pacíficos!
|
||||
@1[<name>]=
|
||||
Set game mode for player or yourself=
|
||||
Error: No game mode specified.=
|
||||
|
|
|
@ -10,7 +10,7 @@ Kill player or yourself=Tuez un joueur ou vous-même
|
|||
Can use /say=Peut utiliser /say
|
||||
<message>=<message>
|
||||
Send a message to every player=Envoyez un message à chaque joueur
|
||||
Invalid usage, see /help say.=Utilisation non valide, voir /help say.
|
||||
Invalid usage, see /help @1.=Utilisation non valide, voir /help @1.
|
||||
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <NodeString>
|
||||
Set node at given position=Placer le noeud à une position donnée
|
||||
Invalid node=Noeud non valide
|
||||
|
@ -21,3 +21,6 @@ Ban list: @1=Liste d'interdiction: @1
|
|||
Show who is logged on=Afficher qui est connecté
|
||||
Displays the world seed=Affiche la graine du monde
|
||||
Only peaceful mobs allowed!=Seuls les mobs pacifiques sont autorisées!
|
||||
@1[<name>]=
|
||||
Set game mode for player or yourself=
|
||||
Error: No game mode specified.=
|
||||
|
|
|
@ -10,7 +10,7 @@ Kill player or yourself=Zabij gracza lub siebie
|
|||
Can use /say=Może używać /say
|
||||
<message>=<wiadomość>
|
||||
Send a message to every player=Wyślij wiadomość do każdego gracza
|
||||
Invalid usage, see /help say.=Niepoprawne użyciu, zobacz /help say.
|
||||
Invalid usage, see /help @1.=Niepoprawne użyciu, zobacz /help @1.
|
||||
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <ID Node'a>
|
||||
Set node at given position=Ustaw node w danej pozycji
|
||||
Invalid node=Niepoprawny node
|
||||
|
@ -21,3 +21,6 @@ Ban list: @1=Lista zbanowanych: @1
|
|||
Show who is logged on=Pokaż zalogowanych
|
||||
Displays the world seed=Wyświetl ziarno świata
|
||||
Only peaceful mobs allowed!=Tylko pokojowe moby dozwolone!
|
||||
@1[<name>]=
|
||||
Set game mode for player or yourself=
|
||||
Error: No game mode specified.=
|
||||
|
|
|
@ -10,7 +10,7 @@ Kill player or yourself=Убить игрока или себя
|
|||
Can use /say=Можно использовать /say
|
||||
<message>=<сообщение>
|
||||
Send a message to every player=Отправляет сообщение всем игрокам
|
||||
Invalid usage, see /help say.=Недопустимое использование, см. /help say.
|
||||
Invalid usage, see /help @1.=Недопустимое использование, см. /help @1.
|
||||
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <СтрокаУзла>
|
||||
Set node at given position=Устанавливает узел в заданной позиции
|
||||
Invalid node=Неправильный узел
|
||||
|
@ -21,3 +21,6 @@ Ban list: @1=Бан-лист: @1
|
|||
Show who is logged on=Показывает, кто подключён
|
||||
Displays the world seed=Показывает значение зерна мира (seed)
|
||||
Only peaceful mobs allowed!=Включены только мирные мобы!
|
||||
@1[<name>]=@1[<имя>]
|
||||
Set game mode for player or yourself=Задаёт режим игры для игрока или для вас
|
||||
Error: No game mode specified.=Ошибка: Режим игры не указан.
|
||||
|
|
|
@ -10,7 +10,7 @@ Kill player or yourself=
|
|||
Can use /say=
|
||||
<message>=
|
||||
Send a message to every player=
|
||||
Invalid usage, see /help say.=
|
||||
Invalid usage, see /help @1.=
|
||||
<X>,<Y>,<Z> <NodeString>=
|
||||
Set node at given position=
|
||||
Invalid node=
|
||||
|
@ -21,3 +21,6 @@ Ban list: @1=
|
|||
Show who is logged on=
|
||||
Displays the world seed=
|
||||
Only peaceful mobs allowed!=
|
||||
@1[<name>]=
|
||||
Set game mode for player or yourself=
|
||||
Error: No game mode specified.=
|
||||
|
|
|
@ -10,7 +10,7 @@ minetest.register_chatcommand("say", {
|
|||
privs = {announce=true},
|
||||
func = function(name, param)
|
||||
if not param then
|
||||
return false, S("Invalid usage, see /help say.")
|
||||
return false, S("Invalid usage, see /help @1.", "say")
|
||||
end
|
||||
minetest.chat_send_all(("["..name.."] "..param))
|
||||
return true
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
local flights_kick_threshold = 10
|
||||
local suffocations_kick_threshold = 1
|
||||
|
||||
local after = minetest.after
|
||||
local get_connected_players = minetest.get_connected_players
|
||||
local get_node = minetest.get_node
|
||||
local get_objects_inside_radius = minetest.get_objects_inside_radius
|
||||
local get_player_by_name = minetest.get_player_by_name
|
||||
local kick_player = minetest.kick_player
|
||||
local set_node = minetest.set_node
|
||||
|
||||
local ceil = math.ceil
|
||||
local floor = math.floor
|
||||
|
||||
local distance = vector.distance
|
||||
|
||||
local window_size = 10
|
||||
local detection_interval = 1.7
|
||||
local step_seconds = detection_interval / window_size
|
||||
local joined_players = {}
|
||||
|
||||
local function update_player(player_object)
|
||||
if not player_object then return end
|
||||
local name = player_object:get_player_name()
|
||||
if not name then return end
|
||||
|
||||
local pos = player_object:get_pos()
|
||||
local x, y, z = floor(pos.x), floor(pos.y-0.1), floor(pos.z)
|
||||
|
||||
if mcl_playerplus.elytra then
|
||||
local elytra = mcl_playerplus.elytra[player_object]
|
||||
if elytra and elytra.active then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local air = get_node({x = x , y = y , z = z }).name == "air"
|
||||
and get_node({x = x , y = y , z = z + 1}).name == "air"
|
||||
and get_node({x = x , y = y + 1, z = z }).name == "air"
|
||||
and get_node({x = x , y = y + 1, z = z + 1}).name == "air"
|
||||
and get_node({x = x + 1, y = y , z = z }).name == "air"
|
||||
and get_node({x = x + 1, y = y , z = z + 1}).name == "air"
|
||||
and get_node({x = x + 1, y = y + 1, z = z }).name == "air"
|
||||
and get_node({x = x + 1, y = y + 1, z = z + 1}).name == "air"
|
||||
|
||||
local player_data = {
|
||||
pos = pos,
|
||||
velocity = player_object:get_velocity(),
|
||||
air = air
|
||||
}
|
||||
|
||||
if joined_players[name] then
|
||||
local window_offset = (joined_players[name].window_offset + 1) % window_size
|
||||
joined_players[name].window_offset = window_offset
|
||||
joined_players[name][window_offset] = player_data
|
||||
else
|
||||
joined_players[name] = {
|
||||
window_offset = 0,
|
||||
[0] = player_data,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function check_player(name)
|
||||
if minetest.is_creative_enabled(name) then return end
|
||||
local data = joined_players[name]
|
||||
if not data then return end
|
||||
if not data[0] then return end
|
||||
|
||||
local always_air = true
|
||||
local falling = data[0].velocity.y < 0
|
||||
for i = 0, window_size - 1 do
|
||||
local derivative = data[i]
|
||||
local not_enough_data = not derivative
|
||||
if not_enough_data then
|
||||
return
|
||||
end
|
||||
always_air = always_air and derivative.air
|
||||
falling = falling or derivative.velocity.y < 0
|
||||
end
|
||||
if always_air and not falling then
|
||||
-- fly detected
|
||||
if not data.flights then
|
||||
data.flights = 1
|
||||
else
|
||||
data.flights = data.flights + 1
|
||||
if data.flights >= flights_kick_threshold then
|
||||
kick_player(name, "flights")
|
||||
end
|
||||
end
|
||||
local obj_player = minetest.get_player_by_name(name)
|
||||
if not obj_player then
|
||||
kick_player(name, "flights")
|
||||
end
|
||||
local velocity = obj_player:get_velocity()
|
||||
local pos = obj_player:get_pos()
|
||||
local x, y, z = floor(pos.x), floor(pos.y), floor(pos.z)
|
||||
while ( get_node({x = x , y = y, z = z }).name == "air"
|
||||
and get_node({x = x , y = y, z = z + 1}).name == "air"
|
||||
and get_node({x = x + 1, y = y, z = z }).name == "air"
|
||||
and get_node({x = x + 1, y = y, z = z + 1}).name == "air"
|
||||
) do
|
||||
y = y - 1
|
||||
end
|
||||
obj_player:set_velocity({x = velocity.x, y = -10, z = velocity.z})
|
||||
obj_player:set_pos({x = x, y = y + 0.5, z = z})
|
||||
end
|
||||
end
|
||||
|
||||
local function remove_player(player_object)
|
||||
if not player_object then return end
|
||||
local name = player_object:get_player_name()
|
||||
if not name then return end
|
||||
minetest.after(step_seconds, function()
|
||||
joined_players[name] = nil
|
||||
end)
|
||||
end
|
||||
|
||||
local function step()
|
||||
for _, player in pairs(get_connected_players()) do
|
||||
update_player(player)
|
||||
check_player(player:get_player_name())
|
||||
end
|
||||
after(step_seconds, step)
|
||||
end
|
||||
|
||||
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
|
||||
if not oldnode then return end
|
||||
if not placer then return end
|
||||
if oldnode.name ~= "air" then return end
|
||||
if not placer:is_player() then return end
|
||||
local placer_pos = placer:get_pos()
|
||||
local placer_distance = distance(pos, placer_pos)
|
||||
if placer_distance < 13 then return end
|
||||
local is_choker = false
|
||||
for _, object in pairs(get_objects_inside_radius(pos, 2)) do
|
||||
if object and object:is_player() then
|
||||
local player_head_pos = object:get_pos()
|
||||
player_head_pos.y = player_head_pos.y + 1.5
|
||||
local player_head_distance = distance(pos, player_head_pos)
|
||||
if player_head_distance < 0.7 then
|
||||
after(0.05, function(node)
|
||||
set_node(pos, node)
|
||||
end, oldnode)
|
||||
is_choker = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if not is_choker then return end
|
||||
-- cheater choked the player from distance greater than 12:
|
||||
local name = placer:get_player_name()
|
||||
local data = joined_players[name]
|
||||
if not data then
|
||||
joined_players[name].suffocations = 1
|
||||
data = joined_players[name]
|
||||
else
|
||||
if not data.suffocations then
|
||||
data.suffocations = 1
|
||||
else
|
||||
data.suffocations = data.suffocations + 1
|
||||
end
|
||||
end
|
||||
if data.suffocations >= suffocations_kick_threshold then
|
||||
kick_player(name, "choker")
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_joinplayer(update_player)
|
||||
|
||||
minetest.register_on_leaveplayer(remove_player)
|
||||
|
||||
after(step_seconds, step)
|
Loading…
Reference in New Issue