New Mod System
This commit is contained in:
parent
80f416d514
commit
bbcd249544
@ -40,4 +40,137 @@ function core.run_server_chatcommand(cmd, param)
|
||||
core.send_chat_message("/" .. cmd .. " " .. param)
|
||||
end
|
||||
|
||||
core.register_chatcommand("say", {
|
||||
description = "Send raw text",
|
||||
func = function(text)
|
||||
core.send_chat_message(text)
|
||||
return true
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("teleport", {
|
||||
params = "<X>,<Y>,<Z>",
|
||||
description = "Teleport to coordinates.",
|
||||
func = function(param)
|
||||
local success, pos = core.parse_pos(param)
|
||||
if success then
|
||||
core.localplayer:set_pos(pos)
|
||||
return true, "Teleporting to " .. core.pos_to_string(pos)
|
||||
end
|
||||
return false, pos
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("teleportjump", {
|
||||
params = "<X>,<Y>,<Z>",
|
||||
description = "Teleport to relative coordinates.",
|
||||
func = function(param)
|
||||
local success, pos = core.parse_relative_pos(param)
|
||||
if success then
|
||||
core.localplayer:set_pos(pos)
|
||||
return true, "Teleporting to " .. core.pos_to_string(pos)
|
||||
end
|
||||
return false, pos
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("wielded", {
|
||||
description = "Print itemstring of wieleded item",
|
||||
func = function()
|
||||
return true, core.localplayer:get_wielded_item():get_name()
|
||||
end
|
||||
})
|
||||
|
||||
core.register_chatcommand("disconnect", {
|
||||
description = "Exit to main menu",
|
||||
func = function(param)
|
||||
core.disconnect()
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("players", {
|
||||
description = "List online players",
|
||||
func = function(param)
|
||||
return true, "Online players: " .. table.concat(core.get_player_names(), ", ")
|
||||
end
|
||||
})
|
||||
|
||||
core.register_chatcommand("kill", {
|
||||
description = "Kill yourself",
|
||||
func = function()
|
||||
core.send_damage(10000)
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("set", {
|
||||
params = "([-n] <name> <value>) | <name>",
|
||||
description = "Set or read client configuration setting",
|
||||
func = function(param)
|
||||
local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)")
|
||||
if arg and arg == "-n" and setname and setvalue then
|
||||
core.settings:set(setname, setvalue)
|
||||
return true, setname .. " = " .. setvalue
|
||||
end
|
||||
|
||||
setname, setvalue = string.match(param, "([^ ]+) (.+)")
|
||||
if setname and setvalue then
|
||||
if not core.settings:get(setname) then
|
||||
return false, "Failed. Use '.set -n <name> <value>' to create a new setting."
|
||||
end
|
||||
core.settings:set(setname, setvalue)
|
||||
return true, setname .. " = " .. setvalue
|
||||
end
|
||||
|
||||
setname = string.match(param, "([^ ]+)")
|
||||
if setname then
|
||||
setvalue = core.settings:get(setname)
|
||||
if not setvalue then
|
||||
setvalue = "<not set>"
|
||||
end
|
||||
return true, setname .. " = " .. setvalue
|
||||
end
|
||||
|
||||
return false, "Invalid parameters (see .help set)."
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("findnodes", {
|
||||
description = "Scan for one or multible nodes in a radius around you",
|
||||
param = "<radius> <node1>[,<node2>...]",
|
||||
func = function(param)
|
||||
local radius = tonumber(param:split(" ")[1])
|
||||
local nodes = param:split(" ")[2]:split(",")
|
||||
local pos = core.localplayer:get_pos()
|
||||
local fpos = core.find_node_near(pos, radius, nodes, true)
|
||||
if fpos then
|
||||
return true, "Found " .. table.concat(nodes, " or ") .. " at " .. core.pos_to_string(fpos)
|
||||
end
|
||||
return false, "None of " .. table.concat(nodes, " or ") .. " found in a radius of " .. tostring(radius)
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("place", {
|
||||
params = "<X>,<Y>,<Z>",
|
||||
description = "Place wielded item",
|
||||
func = function(param)
|
||||
local success, pos = core.parse_relative_pos(param)
|
||||
if success then
|
||||
cores.place_node(pos)
|
||||
return true, "Node placed at " .. core.pos_to_string(pos)
|
||||
end
|
||||
return false, pos
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("dig", {
|
||||
params = "<X>,<Y>,<Z>",
|
||||
description = "Dig node",
|
||||
func = function(param)
|
||||
local success, pos = core.parse_relative_pos(param)
|
||||
if success then
|
||||
core.dig_node(pos)
|
||||
return true, "Node at " .. core.pos_to_string(pos) .. " dug"
|
||||
end
|
||||
return false, pos
|
||||
end,
|
||||
})
|
||||
|
8
builtin/client/cheats/chat.lua
Normal file
8
builtin/client/cheats/chat.lua
Normal file
@ -0,0 +1,8 @@
|
||||
core.register_on_receiving_chat_message(function(message)
|
||||
if message:sub(1, 1) == "#" and core.settings:get_bool("ignore_status_messages") ~= false then
|
||||
return true
|
||||
elseif message:find('\1b@mcl_death_messages\1b') and core.settings:get_bool("mark_deathmessages") ~= false then
|
||||
core.display_chat_message(core.colorize("#F25819", "[Deathmessage] ") .. message)
|
||||
return true
|
||||
end
|
||||
end)
|
@ -3,16 +3,16 @@ core.cheats = {
|
||||
["Killaura"] = "killaura",
|
||||
["AntiKnockback"] = "antiknockback",
|
||||
["FastHit"] = "spamclick",
|
||||
["AttachmentFloat"] = "float_above_parent",
|
||||
},
|
||||
["Movement"] = {
|
||||
["Freecam"] = "freecam",
|
||||
["PrivBypass"] = "priv_bypass",
|
||||
["AutoForward"] = "continuous_forward",
|
||||
["PitchMove"] = "pitch_move",
|
||||
["AutoJump"] = "autojump",
|
||||
["Jesus"] = "jesus",
|
||||
["NoSlow"] = "no_slow",
|
||||
|
||||
["AutoSneak"] = "autosneak",
|
||||
},
|
||||
["Render"] = {
|
||||
["Xray"] = "xray",
|
||||
@ -23,7 +23,6 @@ core.cheats = {
|
||||
["Coords"] = "coords",
|
||||
["Tracers"] = "enable_tracers",
|
||||
["ESP"] = "enable_esp",
|
||||
["AttachmentFloat"] = "float_above_parent",
|
||||
},
|
||||
["World"] = {
|
||||
["FastDig"] = "fastdig",
|
||||
@ -31,9 +30,11 @@ core.cheats = {
|
||||
["AutoDig"] = "autodig",
|
||||
["AutoPlace"] = "autoplace",
|
||||
["InstantBreak"] = "instant_break",
|
||||
["IncreasedRange"] = "increase_tool_range",
|
||||
["UnlimitedRange"] = "increase_tool_range_plus",
|
||||
["PointLiquids"] = "point_liquids",
|
||||
["Scaffold"] = "scaffold",
|
||||
["ScaffoldPlus"] = "scaffold_plus",
|
||||
["BlockWater"] = "block_water",
|
||||
["PlaceOnTop"] = "autotnt",
|
||||
["Replace"] = "replace"
|
||||
},
|
||||
["Exploit"] = {
|
||||
["EntitySpeed"] = "entity_speed",
|
||||
@ -42,10 +43,35 @@ core.cheats = {
|
||||
["Player"] = {
|
||||
["NoFallDamage"] = "prevent_natural_damage",
|
||||
["NoForceRotate"] = "no_force_rotate",
|
||||
["IncreasedRange"] = "increase_tool_range",
|
||||
["UnlimitedRange"] = "increase_tool_range_plus",
|
||||
["PointLiquids"] = "point_liquids",
|
||||
["PrivBypass"] = "priv_bypass",
|
||||
["AutoRespawn"] = "autorespawn",
|
||||
},
|
||||
["Chat"] = {
|
||||
["IgnoreStatus"] = "ignore_status_messages",
|
||||
["Deathmessages"] = "mark_deathmessages"
|
||||
},
|
||||
["Inventory"] = {
|
||||
["AutoEject"] = "autoeject",
|
||||
["AutoTool"] = "autotool",
|
||||
["Enderchest"] = function() core.open_enderchest() end,
|
||||
["HandSlot"] = function() core.open_handslot() end,
|
||||
["NextItem"] = "next_item",
|
||||
}
|
||||
}
|
||||
|
||||
function core.register_cheat(cheatname, category, func)
|
||||
core.cheats[category] = core.cheats[category] or {}
|
||||
core.cheats[category][cheatname] = func
|
||||
end
|
||||
|
||||
local cheatpath = core.get_builtin_path() .. "client" .. DIR_DELIM .. "cheats" .. DIR_DELIM
|
||||
|
||||
dofile(cheatpath .. "chat.lua")
|
||||
dofile(cheatpath .. "inventory.lua")
|
||||
dofile(cheatpath .. "movement.lua")
|
||||
dofile(cheatpath .. "player.lua")
|
||||
dofile(cheatpath .. "render.lua")
|
||||
dofile(cheatpath .. "world.lua")
|
117
builtin/client/cheats/inventory.lua
Normal file
117
builtin/client/cheats/inventory.lua
Normal file
@ -0,0 +1,117 @@
|
||||
local elapsed_time = 0
|
||||
local tick_time = 0.05
|
||||
|
||||
core.register_globalstep(function(dtime)
|
||||
-- AutoEject
|
||||
if core.settings:get_bool("autoeject") then
|
||||
local player = core.localplayer
|
||||
local list = (core.settings:get("eject_items") or ""):split(",")
|
||||
local inventory = core.get_inventory("current_player")
|
||||
for index, stack in pairs(inventory.main) do
|
||||
if table.indexof(list, stack:get_name()) ~= -1 then
|
||||
local old_index = player:get_wield_index()
|
||||
player:set_wield_index(index - 1)
|
||||
core.drop_selected_item()
|
||||
player:set_wield_index(old_index)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
-- NextItem
|
||||
if core.settings:get_bool("next_item") then
|
||||
elapsed_time = elapsed_time + dtime
|
||||
if elapsed_time < tick_time then return end
|
||||
local player = minetest.localplayer
|
||||
if not player then return end
|
||||
local item = player:get_wielded_item()
|
||||
if item:get_count() == 0 then
|
||||
local index = player:get_wield_index()
|
||||
player:set_wield_index(index + 1)
|
||||
end
|
||||
elapsed_time = 0
|
||||
end
|
||||
end)
|
||||
|
||||
core.register_list_command("eject", "Configure AutoEject", "eject_items")
|
||||
|
||||
-- AutoTool
|
||||
|
||||
local function check_tool(stack, node_groups, old_best_time)
|
||||
local toolcaps = stack:get_tool_capabilities()
|
||||
if not toolcaps then return end
|
||||
local best_time = old_best_time
|
||||
for group, groupdef in pairs(toolcaps.groupcaps) do
|
||||
local level = node_groups[group]
|
||||
if level then
|
||||
local this_time = groupdef.times[level]
|
||||
if this_time < best_time then
|
||||
best_time = this_time
|
||||
end
|
||||
end
|
||||
end
|
||||
return best_time < old_best_time, best_time
|
||||
end
|
||||
|
||||
core.register_on_punchnode(function(pos, node)
|
||||
if not minetest.settings:get_bool("autotool") then return end
|
||||
local player = minetest.localplayer
|
||||
local inventory = minetest.get_inventory("current_player")
|
||||
local node_groups = minetest.get_node_def(node.name).groups
|
||||
local new_index = player:get_wield_index()
|
||||
local is_better, best_time = false, math.huge
|
||||
is_better, best_time = check_tool(player:get_wielded_item(), node_groups, best_time)
|
||||
is_better, best_time = check_tool(inventory.hand[1], node_groups, best_time)
|
||||
for index, stack in pairs(inventory.main) do
|
||||
is_better, best_time = check_tool(stack, node_groups, best_time)
|
||||
if is_better then
|
||||
new_index = index - 1
|
||||
end
|
||||
end
|
||||
player:set_wield_index(new_index)
|
||||
end)
|
||||
|
||||
-- Enderchest
|
||||
|
||||
function get_itemslot_bg(x, y, w, h)
|
||||
local out = ""
|
||||
for i = 0, w - 1, 1 do
|
||||
for j = 0, h - 1, 1 do
|
||||
out = out .."image["..x+i..","..y+j..";1,1;mcl_formspec_itemslot.png]"
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
local enderchest_formspec = "size[9,8.75]"..
|
||||
"label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", "Ender Chest")).."]"..
|
||||
"list[current_player;enderchest;0,0.5;9,3;]"..
|
||||
get_itemslot_bg(0,0.5,9,3)..
|
||||
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", "Inventory")).."]"..
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
get_itemslot_bg(0,7.74,9,1)..
|
||||
"listring[current_player;enderchest]"..
|
||||
"listring[current_player;main]"
|
||||
|
||||
function core.open_enderchest()
|
||||
core.show_formspec("__builtin__:enderchest", enderchest_formspec)
|
||||
end
|
||||
|
||||
-- HandSlot
|
||||
|
||||
local hand_formspec = "size[9,8.75]"..
|
||||
"label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", "Hand")).."]"..
|
||||
"list[current_player;hand;0,0.5;1,1;]"..
|
||||
get_itemslot_bg(0,0.5,1,1)..
|
||||
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", "Inventory")).."]"..
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
get_itemslot_bg(0,7.74,9,1)..
|
||||
"listring[current_player;hand]"..
|
||||
"listring[current_player;main]"
|
||||
|
||||
function core.open_handslot()
|
||||
minetest.show_formspec("__builtin__:hand", hand_formspec)
|
||||
end
|
14
builtin/client/cheats/movement.lua
Normal file
14
builtin/client/cheats/movement.lua
Normal file
@ -0,0 +1,14 @@
|
||||
-- autosneak
|
||||
|
||||
local autosneak_was_enabled = false
|
||||
|
||||
core.register_globalstep(function()
|
||||
if core.settings:get_bool("autosneak") then
|
||||
core.set_keypress("sneak", true)
|
||||
autosneak_was_enabled = true
|
||||
elseif autosneak_was_enabled then
|
||||
autosneak_was_enabled = false
|
||||
core.set_keypress("sneak", false)
|
||||
end
|
||||
end)
|
||||
|
39
builtin/client/cheats/player.lua
Normal file
39
builtin/client/cheats/player.lua
Normal file
@ -0,0 +1,39 @@
|
||||
local death_formspec = ""
|
||||
.. "size[11,5.5]"
|
||||
.. "bgcolor[#320000b4;true]"
|
||||
.. "label[4.85,1.35;" .. "You died" .. "]"
|
||||
.. "button_exit[2,3;3,0.5;btn_respawn;" .. "Respawn" .. "]"
|
||||
.. "button_exit[6,3;3,0.5;btn_ghost_mode;" .. "Ghost Mode" .. "]"
|
||||
.. "set_focus[btn_respawn;true]"
|
||||
|
||||
core.register_on_death(function()
|
||||
core.display_chat_message("You died at " .. core.pos_to_string(vector.round(core.localplayer:get_pos())) .. ".")
|
||||
if core.settings:get_bool("autorespawn") then
|
||||
core.send_respawn()
|
||||
else
|
||||
core.show_formspec("__builtin__:death", death_formspec)
|
||||
end
|
||||
end)
|
||||
|
||||
core.register_on_formspec_input(function(formname, fields)
|
||||
if formname == "__builtin__:death" then
|
||||
if fields.btn_ghost_mode then
|
||||
core.display_chat_message("You are in ghost mode. Use .respawn to Respawn.")
|
||||
else
|
||||
core.send_respawn()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
core.register_chatcommand("respawn", {
|
||||
description = "Respawn when in ghost mode",
|
||||
func = function()
|
||||
if core.localplayer:get_hp() == 0 then
|
||||
core.send_respawn()
|
||||
core.display_chat_message("Respawned.")
|
||||
else
|
||||
core.display_chat_message("You are not in ghost mode.")
|
||||
end
|
||||
end
|
||||
})
|
||||
|
1
builtin/client/cheats/render.lua
Normal file
1
builtin/client/cheats/render.lua
Normal file
@ -0,0 +1 @@
|
||||
core.register_list_command("xray", "Configure X-Ray", "xray_nodes")
|
53
builtin/client/cheats/world.lua
Normal file
53
builtin/client/cheats/world.lua
Normal file
@ -0,0 +1,53 @@
|
||||
core.register_on_dignode(function(pos)
|
||||
if core.settings:get_bool("replace") then
|
||||
core.after(0, minetest.place_node, pos)
|
||||
end
|
||||
end)
|
||||
|
||||
local etime = 0
|
||||
|
||||
core.register_globalstep(function(dtime)
|
||||
etime = etime + dtime
|
||||
if etime < 1 then return end
|
||||
local player = core.localplayer
|
||||
if not player then return end
|
||||
local pos = player:get_pos()
|
||||
local item = player:get_wielded_item()
|
||||
local def = core.get_item_def(item:get_name())
|
||||
local nodes_per_tick = tonumber(minetest.settings:get("nodes_per_tick")) or 8
|
||||
if item and item:get_count() > 0 and def and def.node_placement_prediction ~= "" then
|
||||
if core.settings:get_bool("scaffold") then
|
||||
core.place_node(vector.add(pos, {x = 0, y = -0.6, z = 0}))
|
||||
elseif core.settings:get_bool("scaffold_plus") then
|
||||
local z = pos.z
|
||||
local positions = {
|
||||
{x = 0, y = -0.6, z = 0},
|
||||
{x = 1, y = -0.6, z = 0},
|
||||
{x = -1, y = -0.6, z = 0},
|
||||
{x = -1, y = -0.6, z = -1},
|
||||
{x = 0, y = -0.6, z = -1},
|
||||
{x = 1, y = -0.6, z = -1},
|
||||
{x = -1, y = -0.6, z = 1},
|
||||
{x = 0, y = -0.6, z = 1},
|
||||
{x = 1, y = -0.6, z = 1}
|
||||
}
|
||||
for i, p in pairs(positions) do
|
||||
core.place_node(vector.add(pos, p))
|
||||
end
|
||||
elseif core.settings:get_bool("block_water") then
|
||||
local positions = core.find_nodes_near(pos, 5, {"mcl_core:water_source", "mcl_core:water_floating"}, true)
|
||||
for i, p in pairs(positions) do
|
||||
if i > nodes_per_tick then return end
|
||||
core.place_node(p)
|
||||
end
|
||||
elseif core.settings:get_bool("autotnt") then
|
||||
local positions = core.find_nodes_near_under_air_except(pos, 5, item:get_name(), true)
|
||||
for i, p in pairs(positions) do
|
||||
if i > nodes_per_tick then return end
|
||||
core.place_node(vector.add(p, {x = 0, y = 1, z = 0}))
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -9,5 +9,5 @@ dofile(commonpath .. "chatcommands.lua")
|
||||
dofile(commonpath .. "vector.lua")
|
||||
dofile(clientpath .. "util.lua")
|
||||
dofile(clientpath .. "chatcommands.lua")
|
||||
dofile(clientpath .. "cheats.lua")
|
||||
dofile(clientpath .. "cheats"..DIR_DELIM.."init.lua")
|
||||
|
||||
|
@ -29,6 +29,49 @@ function core.override_chatcommand(name, redefinition)
|
||||
core.registered_chatcommands[name] = chatcommand
|
||||
end
|
||||
|
||||
function core.register_list_command(command, desc, setting)
|
||||
local def = {}
|
||||
def.description = desc
|
||||
def.params = "del <item> | add <item> | list"
|
||||
function def.func(param)
|
||||
local list = (minetest.settings:get(setting) or ""):split(",")
|
||||
if param == "list" then
|
||||
return true, table.concat(list, ", ")
|
||||
else
|
||||
local sparam = param:split(" ")
|
||||
local cmd = sparam[1]
|
||||
local item = sparam[2]
|
||||
if cmd == "del" then
|
||||
if not item then
|
||||
return false, "Missing item."
|
||||
end
|
||||
local i = table.indexof(list, item)
|
||||
if i == -1 then
|
||||
return false, item .. " is not on the list."
|
||||
else
|
||||
table.remove(list, i)
|
||||
core.settings:set(setting, table.concat(list, ","))
|
||||
return true, "Removed " .. item .. " from the list."
|
||||
end
|
||||
elseif cmd == "add" then
|
||||
if not item then
|
||||
return false, "Missing item."
|
||||
end
|
||||
local i = table.indexof(list, item)
|
||||
if i ~= -1 then
|
||||
return false, item .. " is already on the list."
|
||||
else
|
||||
table.insert(list, item)
|
||||
core.settings:set(setting, table.concat(list, ","))
|
||||
return true, "Added " .. item .. " to the list."
|
||||
end
|
||||
end
|
||||
end
|
||||
return false, "Invalid usage. (See /help " .. command .. ")"
|
||||
end
|
||||
core.register_chatcommand(command, def)
|
||||
end
|
||||
|
||||
local cmd_marker = "/"
|
||||
|
||||
local function gettext(...)
|
||||
|
@ -594,6 +594,67 @@ function core.colorize(color, message)
|
||||
return table.concat(lines, "\n") .. core.get_color_escape_sequence("#ffffff")
|
||||
end
|
||||
|
||||
local function rgb_to_hex(rgb)
|
||||
local hexadecimal = '#'
|
||||
|
||||
for key, value in pairs(rgb) do
|
||||
local hex = ''
|
||||
|
||||
while(value > 0)do
|
||||
local index = math.fmod(value, 16) + 1
|
||||
value = math.floor(value / 16)
|
||||
hex = string.sub('0123456789ABCDEF', index, index) .. hex
|
||||
end
|
||||
|
||||
if(string.len(hex) == 0)then
|
||||
hex = '00'
|
||||
|
||||
elseif(string.len(hex) == 1)then
|
||||
hex = '0' .. hex
|
||||
end
|
||||
|
||||
hexadecimal = hexadecimal .. hex
|
||||
end
|
||||
|
||||
return hexadecimal
|
||||
end
|
||||
|
||||
local function color_from_hue(hue)
|
||||
local h = hue / 60
|
||||
local c = 255
|
||||
local x = (1 - math.abs(h%2 - 1)) * 255
|
||||
|
||||
local i = math.floor(h);
|
||||
if (i == 0) then
|
||||
return rgb_to_hex({c, x, 0})
|
||||
elseif (i == 1) then
|
||||
return rgb_to_hex({x, c, 0})
|
||||
elseif (i == 2) then
|
||||
return rgb_to_hex({0, c, x})
|
||||
elseif (i == 3) then
|
||||
return rgb_to_hex({0, x, c});
|
||||
elseif (i == 4) then
|
||||
return rgb_to_hex({x, 0, c});
|
||||
else
|
||||
return rgb_to_hex({c, 0, x});
|
||||
end
|
||||
end
|
||||
|
||||
function core.rainbow(input)
|
||||
local step = 360 / input:len()
|
||||
local hue = 0
|
||||
local output = ""
|
||||
for i = 1, input:len() do
|
||||
local char = input:sub(i,i)
|
||||
if char:match("%s") then
|
||||
output = output .. char
|
||||
else
|
||||
output = output .. core.get_color_escape_sequence(color_from_hue(hue)) .. char
|
||||
end
|
||||
hue = hue + step
|
||||
end
|
||||
return output
|
||||
end
|
||||
|
||||
function core.strip_foreground_colors(str)
|
||||
return (str:gsub(ESCAPE_CHAR .. "%(c@[^)]+%)", ""))
|
||||
|
@ -17,8 +17,10 @@
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local dragonfire_team = {
|
||||
"Elias Fleckenstein <eliasfleckenstein@web.de> [Main Developer]",
|
||||
"DerZombiiie [Bots, User Support]",
|
||||
"Elias Fleckenstein",
|
||||
"cora",
|
||||
"system32",
|
||||
"DerZombiiie",
|
||||
}
|
||||
|
||||
local core_developers = {
|
||||
|
@ -2217,13 +2217,10 @@ contentdb_flag_blacklist (ContentDB Flag Blacklist) string nonfree, desktop_defa
|
||||
|
||||
fullbright (Fullbright) bool false
|
||||
|
||||
# Enable xray, requires fullbright
|
||||
xray (X-Ray) bool false
|
||||
xray (XRay) bool false
|
||||
|
||||
# Node to apply xray
|
||||
xray_node (X-RayTexture) string default:stone
|
||||
xray_nodes (XRay Nodes) string default:stone,mcl_core:stone
|
||||
|
||||
# Make the Client think it has all privs
|
||||
priv_bypass (PrivBypass) bool true
|
||||
|
||||
fastdig (FastDig) bool false
|
||||
@ -2246,7 +2243,6 @@ increase_tool_range (IncreasedRange) bool true
|
||||
|
||||
increase_tool_range_plus (IncreasedRangePlus) bool true
|
||||
|
||||
# HUD Flags Bypass
|
||||
hud_flags_bypass (HUDBypass) bool true
|
||||
|
||||
antiknockback (AntiKnockback) bool false
|
||||
@ -2274,3 +2270,29 @@ enable_tracers (Tracers) bool false
|
||||
enable_esp (ESP) bool false
|
||||
|
||||
no_slow (NoSlow) bool false
|
||||
|
||||
ignore_status_messages (IgnoreStatus) bool true
|
||||
|
||||
mark_deathmessages (Deathmessages) bool true
|
||||
|
||||
autosneak (AutoSneak) bool false
|
||||
|
||||
autoeject (AutoEject) bool false
|
||||
|
||||
eject_items (AutoEject Items) string
|
||||
|
||||
autotool (AutoTool) bool false
|
||||
|
||||
autorespawn (AutoRespawn) bool false
|
||||
|
||||
next_item (NextItem) bool false
|
||||
|
||||
scaffold (Scaffold) bool false
|
||||
|
||||
scaffold_plus (ScaffoldPlus) bool false
|
||||
|
||||
block_water (BlockWater) bool false
|
||||
|
||||
autotnt (PlaceOnTop) bool false
|
||||
|
||||
replace (Replace) bool false
|
||||
|
@ -1,21 +0,0 @@
|
||||
autoeat = {}
|
||||
|
||||
local last_step_eating = false
|
||||
|
||||
minetest.register_on_damage_taken(function()
|
||||
if not minetest.settings:get_bool("autoeat") then return end
|
||||
local player = minetest.localplayer
|
||||
player:set_wield_index(0)
|
||||
minetest.place_node(player:get_pos())
|
||||
autoeat.eating = true
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
if last_step_eating then
|
||||
autoeat.eating, last_step_eating = false, false
|
||||
elseif autoeat.eating then
|
||||
last_step_eating = true
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_cheat("AutoEat", "Player", "autoeat")
|
@ -1,3 +0,0 @@
|
||||
name = autoeat
|
||||
description = Automatically eat when damage was taken, assuming that there is food in the first hotbar slot. This is only useful when used in combination with an afk bot, like schematicas.
|
||||
author = Fleckenstein
|
@ -1 +0,0 @@
|
||||
autoeat (Automatically eat when damage was taken) bool false
|
@ -1,13 +0,0 @@
|
||||
local was_enabled = false
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
if minetest.settings:get_bool("autosneak") then
|
||||
minetest.set_keypress("sneak", true)
|
||||
was_enabled = true
|
||||
elseif was_enabled then
|
||||
was_enabled = false
|
||||
minetest.set_keypress("sneak", false)
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_cheat("AutoSneak", "Movement", "autosneak")
|
@ -1,3 +0,0 @@
|
||||
name = autosneak
|
||||
desciption = Adds the AutoSneak feature to dragonfire.
|
||||
author = Fleckenstein
|
@ -1 +0,0 @@
|
||||
autosneak (AutoSneak) bool false
|
@ -1,33 +0,0 @@
|
||||
function chat.send(message)
|
||||
local starts_with = message:sub(1, 1)
|
||||
|
||||
if starts_with == "/" or starts_with == "." then return end
|
||||
|
||||
local reverse = minetest.settings:get_bool("chat_reverse")
|
||||
|
||||
if reverse then
|
||||
local msg = ""
|
||||
for i = 1, #message do
|
||||
msg = message:sub(i, i) .. msg
|
||||
end
|
||||
message = msg
|
||||
end
|
||||
|
||||
local color = minetest.settings:get("chat_color")
|
||||
|
||||
if color then
|
||||
local msg
|
||||
if color == "rainbow" then
|
||||
msg = chat.rainbow(message)
|
||||
else
|
||||
msg = minetest.colorize(color, message)
|
||||
end
|
||||
message = msg
|
||||
end
|
||||
|
||||
minetest.send_chat_message(message)
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_on_sending_chat_message(chat.send)
|
||||
|
@ -1,13 +0,0 @@
|
||||
chat = {}
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
|
||||
chat.rainbow = dofile(modpath .. "/rainbow.lua")
|
||||
|
||||
dofile(modpath .. "/colors.lua")
|
||||
dofile(modpath .. "/spam.lua")
|
||||
dofile(modpath .. "/status.lua")
|
||||
dofile(modpath .. "/leak.lua")
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
local etime = 0
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if not minetest.settings:get_bool("leak") then return end
|
||||
etime = etime + dtime
|
||||
if etime < 5 then return end
|
||||
etime = 0
|
||||
local player = minetest.localplayer
|
||||
minetest.send_chat_message(minetest.pos_to_string(vector.floor(player:get_pos())))
|
||||
end)
|
||||
|
||||
minetest.register_cheat("Leak", "Player", "leak")
|
@ -1,3 +0,0 @@
|
||||
name = chat
|
||||
author = Fleckenstein
|
||||
description = The chat modifications of Dragonfireclient
|
@ -1,61 +0,0 @@
|
||||
local function rgb_to_hex(rgb)
|
||||
local hexadecimal = '#'
|
||||
|
||||
for key, value in pairs(rgb) do
|
||||
local hex = ''
|
||||
|
||||
while(value > 0)do
|
||||
local index = math.fmod(value, 16) + 1
|
||||
value = math.floor(value / 16)
|
||||
hex = string.sub('0123456789ABCDEF', index, index) .. hex
|
||||
end
|
||||
|
||||
if(string.len(hex) == 0)then
|
||||
hex = '00'
|
||||
|
||||
elseif(string.len(hex) == 1)then
|
||||
hex = '0' .. hex
|
||||
end
|
||||
|
||||
hexadecimal = hexadecimal .. hex
|
||||
end
|
||||
|
||||
return hexadecimal
|
||||
end
|
||||
|
||||
local function color_from_hue(hue)
|
||||
local h = hue / 60
|
||||
local c = 255
|
||||
local x = (1 - math.abs(h%2 - 1)) * 255
|
||||
|
||||
local i = math.floor(h);
|
||||
if (i == 0) then
|
||||
return rgb_to_hex({c, x, 0})
|
||||
elseif (i == 1) then
|
||||
return rgb_to_hex({x, c, 0})
|
||||
elseif (i == 2) then
|
||||
return rgb_to_hex({0, c, x})
|
||||
elseif (i == 3) then
|
||||
return rgb_to_hex({0, x, c});
|
||||
elseif (i == 4) then
|
||||
return rgb_to_hex({x, 0, c});
|
||||
else
|
||||
return rgb_to_hex({c, 0, x});
|
||||
end
|
||||
end
|
||||
|
||||
return function(input)
|
||||
local step = 360 / input:len()
|
||||
local hue = 0
|
||||
local output = ""
|
||||
for i = 1, input:len() do
|
||||
local char = input:sub(i,i)
|
||||
if char:match("%s") then
|
||||
output = output .. char
|
||||
else
|
||||
output = output .. minetest.get_color_escape_sequence(color_from_hue(hue)) .. char
|
||||
end
|
||||
hue = hue + step
|
||||
end
|
||||
return output
|
||||
end
|
@ -1,6 +0,0 @@
|
||||
chat_color (Chat Color) string white
|
||||
chat_reverse (Reverse Chat messages) bool false
|
||||
chat_enable_spam (Spam Chat) bool false
|
||||
chat_spam (Message to spam into Chat) string
|
||||
ignore_status_messages (Ignore status messages from server) bool true
|
||||
leak (Frequently leak your coordinates to chat) bool false
|
@ -1,12 +0,0 @@
|
||||
local etime = 0
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
etime = etime + dtime
|
||||
if etime < 10/8 then return end
|
||||
etime = 0
|
||||
local spam = minetest.settings:get("chat_spam")
|
||||
local enable_spam = minetest.settings:get("chat_enable_spam")
|
||||
if enable_spam and spam then
|
||||
local _ = chat.send(spam) or minetest.send_chat_message(spam)
|
||||
end
|
||||
end)
|
@ -1,7 +0,0 @@
|
||||
minetest.register_on_receiving_chat_message(function(message)
|
||||
if message:sub(1, 1) == "#" and minetest.settings:get_bool("ignore_status_messages") ~= false then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_cheat("IgnoreStatus", "Player", "ignore_status_messages")
|
@ -1,88 +0,0 @@
|
||||
minetest.register_chatcommand("say", {
|
||||
description = "Send raw text",
|
||||
func = function(text)
|
||||
minetest.send_chat_message(text)
|
||||
return true
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("teleport", {
|
||||
params = "<X>,<Y>,<Z>",
|
||||
description = "Teleport to relative coordinates.",
|
||||
func = function(param)
|
||||
local success, pos = minetest.parse_relative_pos(param)
|
||||
if success then
|
||||
minetest.localplayer:set_pos(pos)
|
||||
return true, "Teleporting to " .. minetest.pos_to_string(pos)
|
||||
end
|
||||
return false, pos
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("wielded", {
|
||||
description = "Print itemstring of wieleded item",
|
||||
func = function()
|
||||
return true, minetest.localplayer:get_wielded_item():get_name()
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("disconnect", {
|
||||
description = "Exit to main menu",
|
||||
func = function(param)
|
||||
minetest.disconnect()
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("players", {
|
||||
description = "List online players",
|
||||
func = function(param)
|
||||
return true, "Online players: " .. table.concat(minetest.get_player_names(), ", ")
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("kill", {
|
||||
description = "Kill yourself",
|
||||
func = function()
|
||||
minetest.send_damage(minetest.localplayer:get_hp())
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("hop", {
|
||||
description = "Hop",
|
||||
func = function()
|
||||
minetest.set_keypress("jump", true)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("set", {
|
||||
params = "([-n] <name> <value>) | <name>",
|
||||
description = "Set or read client configuration setting",
|
||||
func = function(param)
|
||||
local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)")
|
||||
if arg and arg == "-n" and setname and setvalue then
|
||||
minetest.settings:set(setname, setvalue)
|
||||
return true, setname .. " = " .. setvalue
|
||||
end
|
||||
|
||||
setname, setvalue = string.match(param, "([^ ]+) (.+)")
|
||||
if setname and setvalue then
|
||||
if not minetest.settings:get(setname) then
|
||||
return false, "Failed. Use '.set -n <name> <value>' to create a new setting."
|
||||
end
|
||||
minetest.settings:set(setname, setvalue)
|
||||
return true, setname .. " = " .. setvalue
|
||||
end
|
||||
|
||||
setname = string.match(param, "([^ ]+)")
|
||||
if setname then
|
||||
setvalue = minetest.settings:get(setname)
|
||||
if not setvalue then
|
||||
setvalue = "<not set>"
|
||||
end
|
||||
return true, setname .. " = " .. setvalue
|
||||
end
|
||||
|
||||
return false, "Invalid parameters (see .help set)."
|
||||
end,
|
||||
})
|
||||
|
@ -1,3 +0,0 @@
|
||||
name = commands
|
||||
author = Fleckenstein
|
||||
description = Misc cheat commands
|
@ -1,19 +0,0 @@
|
||||
minetest.register_globalstep(function()
|
||||
if minetest.settings:get_bool("autoeject") then
|
||||
local player = minetest.localplayer
|
||||
local list = (minetest.settings:get("eject_items") or ""):split(",")
|
||||
local inventory = minetest.get_inventory("current_player")
|
||||
for index, stack in pairs(inventory.main) do
|
||||
if table.indexof(list, stack:get_name()) ~= -1 then
|
||||
local old_index = player:get_wield_index()
|
||||
player:set_wield_index(index - 1)
|
||||
minetest.drop_selected_item()
|
||||
player:set_wield_index(old_index)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_chatcommand("eject", list.new("Configure AutoEject", "eject_items"))
|
||||
minetest.register_cheat("AutoEject", "Player", "autoeject")
|
@ -1,36 +0,0 @@
|
||||
local function check_tool(stack, node_groups, old_best_time)
|
||||
local toolcaps = stack:get_tool_capabilities()
|
||||
if not toolcaps then return end
|
||||
local best_time = old_best_time
|
||||
for group, groupdef in pairs(toolcaps.groupcaps) do
|
||||
local level = node_groups[group]
|
||||
if level then
|
||||
local this_time = groupdef.times[level]
|
||||
if this_time < best_time then
|
||||
best_time = this_time
|
||||
end
|
||||
end
|
||||
end
|
||||
return best_time < old_best_time, best_time
|
||||
end
|
||||
|
||||
minetest.register_on_punchnode(function(pos, node)
|
||||
if not minetest.settings:get_bool("autotool") then return end
|
||||
local player = minetest.localplayer
|
||||
local inventory = minetest.get_inventory("current_player")
|
||||
local node_groups = minetest.get_node_def(node.name).groups
|
||||
local new_index = player:get_wield_index()
|
||||
local is_better, best_time = false, math.huge
|
||||
is_better, best_time = check_tool(player:get_wielded_item(), node_groups, best_time)
|
||||
is_better, best_time = check_tool(inventory.hand[1], node_groups, best_time)
|
||||
for index, stack in pairs(inventory.main) do
|
||||
is_better, best_time = check_tool(stack, node_groups, best_time)
|
||||
if is_better then
|
||||
new_index = index - 1
|
||||
end
|
||||
end
|
||||
player:set_wield_index(new_index)
|
||||
end)
|
||||
|
||||
minetest.register_cheat("AutoTool", "Player", "autotool")
|
||||
|
@ -1,27 +0,0 @@
|
||||
function get_itemslot_bg(x, y, w, h)
|
||||
local out = ""
|
||||
for i = 0, w - 1, 1 do
|
||||
for j = 0, h - 1, 1 do
|
||||
out = out .."image["..x+i..","..y+j..";1,1;mcl_formspec_itemslot.png]"
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
local formspec = "size[9,8.75]"..
|
||||
"label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", "Ender Chest")).."]"..
|
||||
"list[current_player;enderchest;0,0.5;9,3;]"..
|
||||
get_itemslot_bg(0,0.5,9,3)..
|
||||
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", "Inventory")).."]"..
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
get_itemslot_bg(0,7.74,9,1)..
|
||||
"listring[current_player;enderchest]"..
|
||||
"listring[current_player;main]"
|
||||
|
||||
function minetest.open_special_inventory()
|
||||
minetest.show_formspec("enderchest:enderchest", formspec)
|
||||
end
|
||||
|
||||
minetest.register_cheat("Enderchest", "Player", minetest.open_special_inventory)
|
@ -1,27 +0,0 @@
|
||||
function get_itemslot_bg(x, y, w, h)
|
||||
local out = ""
|
||||
for i = 0, w - 1, 1 do
|
||||
for j = 0, h - 1, 1 do
|
||||
out = out .."image["..x+i..","..y+j..";1,1;mcl_formspec_itemslot.png]"
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
local formspec = "size[9,8.75]"..
|
||||
"label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", "Hand")).."]"..
|
||||
"list[current_player;hand;0,0.5;1,1;]"..
|
||||
get_itemslot_bg(0,0.5,1,1)..
|
||||
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", "Inventory")).."]"..
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
get_itemslot_bg(0,7.74,9,1)..
|
||||
"listring[current_player;hand]"..
|
||||
"listring[current_player;main]"
|
||||
|
||||
local function hand()
|
||||
minetest.show_formspec("inventory:hand", formspec)
|
||||
end
|
||||
|
||||
minetest.register_cheat("Hand", "Player", hand)
|
@ -1,11 +0,0 @@
|
||||
inventory_mod = {}
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
|
||||
dofile(modpath .. "/invhack.lua")
|
||||
dofile(modpath .. "/enderchest.lua")
|
||||
dofile(modpath .. "/hand.lua")
|
||||
dofile(modpath .. "/next_item.lua")
|
||||
dofile(modpath .. "/autotool.lua")
|
||||
dofile(modpath .. "/autoeject.lua")
|
@ -1,13 +0,0 @@
|
||||
minetest.register_chatcommand("invhack", {
|
||||
func = function(player)
|
||||
minetest.show_formspec(
|
||||
"invhack:invhack",
|
||||
""
|
||||
.. "size[8,7.5]"
|
||||
.. "list[player:" .. player .. ";main;0,3.5;8,4;]"
|
||||
.. "list[player:" .. player .. ";craft;3,0;3,3;]"
|
||||
.. "list[player:" .. player .. ";craftpreview;7,1;1,1;]"
|
||||
)
|
||||
end
|
||||
})
|
||||
|
@ -1,4 +0,0 @@
|
||||
name = inventory
|
||||
author = Fleckenstein
|
||||
description = The inventory cheats for Dragonfireclient
|
||||
dependencies = list
|
@ -1,18 +0,0 @@
|
||||
local elapsed_time = 0
|
||||
local tick_time = 0.05
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
elapsed_time = elapsed_time + dtime
|
||||
if elapsed_time < tick_time then return end
|
||||
local player = minetest.localplayer
|
||||
if not player then return end
|
||||
local item = player:get_wielded_item()
|
||||
if item:get_count() == 0 and minetest.settings:get_bool("next_item") then
|
||||
local index = player:get_wield_index()
|
||||
player:set_wield_index(index + 1)
|
||||
end
|
||||
elapsed_time = 0
|
||||
end)
|
||||
|
||||
minetest.register_cheat("NextItem", "Player", "next_item")
|
||||
|
@ -1,4 +0,0 @@
|
||||
next_item (NextItem) bool false
|
||||
autotool (AutoTool) bool false
|
||||
autoeject (AutoEject) bool false
|
||||
eject_items (AutoEject Items) string
|
@ -1,47 +0,0 @@
|
||||
list = {}
|
||||
|
||||
function list.new(desc, setting)
|
||||
local def = {}
|
||||
def.description = desc
|
||||
def.params = "del <item> | add <item> | list"
|
||||
function def.func(param)
|
||||
local list = (minetest.settings:get(setting) or ""):split(",")
|
||||
if param == "list" then
|
||||
return true, table.concat(list, ", ")
|
||||
else
|
||||
local sparam = param:split(" ")
|
||||
local cmd = sparam[1]
|
||||
local item = sparam[2]
|
||||
if cmd == "del" then
|
||||
if not item then
|
||||
return false, "Missing item."
|
||||
end
|
||||
local i = table.indexof(list, item)
|
||||
if i == -1 then
|
||||
return false, item .. " is not on the list."
|
||||
else
|
||||
table.remove(list, i)
|
||||
minetest.settings:set(setting, table.concat(list, ","))
|
||||
return true, "Removed " .. item .. " from the list."
|
||||
end
|
||||
elseif cmd == "add" then
|
||||
if not item then
|
||||
return false, "Missing item."
|
||||
end
|
||||
local i = table.indexof(list, item)
|
||||
if i ~= -1 then
|
||||
return false, item .. " is already on the list."
|
||||
else
|
||||
table.insert(list, item)
|
||||
minetest.settings:set(setting, table.concat(list, ","))
|
||||
return true, "Added " .. item .. " to the list."
|
||||
end
|
||||
end
|
||||
end
|
||||
return false, "Invalid usage. (See /help <command>)"
|
||||
end
|
||||
return def
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("xray", list.new("Configure X-Ray", "xray_nodes"))
|
||||
--minetest.register_chatcommand("Configure Search Nodes", "search_nodes")
|
@ -1 +0,0 @@
|
||||
|
@ -1,109 +0,0 @@
|
||||
local positions, index, global_goal
|
||||
|
||||
local function roundvec(v, d)
|
||||
return vector.divide(vector.round(vector.multiply(v, d)), d)
|
||||
end
|
||||
|
||||
local function findpath(pos)
|
||||
global_goal = pos
|
||||
index = 2
|
||||
positions = minetest.find_path(
|
||||
minetest.localplayer:get_pos(),
|
||||
pos,
|
||||
tonumber(minetest.settings:get("goto_max_distance") or 25),
|
||||
tonumber(minetest.settings:get("goto_max_jump") or 1),
|
||||
tonumber(minetest.settings:get("goto_max_drop") or minetest.settings:get_bool("prevent_natural_damage") and 1000 or 5)
|
||||
)
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("goto", {
|
||||
description = "Go to a position (use pathfinding).",
|
||||
param = "<pos>",
|
||||
func = function(param)
|
||||
if positions then
|
||||
return false, "Goto is still active. Use .gotoabort to abort it."
|
||||
end
|
||||
local success, pos = minetest.parse_pos(param)
|
||||
if not success then
|
||||
return false, pos
|
||||
end
|
||||
findpath(pos)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("gotoabort", {
|
||||
description = "Abort goto.",
|
||||
param = "<pos>",
|
||||
func = function(param)
|
||||
if not positions then
|
||||
return false, "Goto is currently not running (and also not walking haha)"
|
||||
end
|
||||
minetest.set_keypress("forward", false)
|
||||
minetest.set_keypress("sneak", false)
|
||||
positions, index, global_goal = nil
|
||||
return true, "Aborted."
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if positions then
|
||||
minetest.set_keypress("forward", true)
|
||||
minetest.set_keypress("sneak", false)
|
||||
local player = minetest.localplayer
|
||||
local pos = player:get_pos()
|
||||
local goal, next_goal = positions[index], positions[index+1]
|
||||
if not goal then
|
||||
positions, index, global_goal = nil
|
||||
minetest.set_keypress("forward", false)
|
||||
minetest.display_chat_message("Reached goal.")
|
||||
return
|
||||
end
|
||||
if next_goal then
|
||||
local d, dn = vector.subtract(pos, goal), vector.subtract(next_goal, goal)
|
||||
for k, v in pairs(dn) do
|
||||
if v ~= 0 and k ~= "y" then
|
||||
local cv = d[k]
|
||||
if v > 0 and cv > 0 or v < 0 and cv < 0 then
|
||||
index = index + 1
|
||||
goal = next_goal
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
local npos = vector.add(goal, {x = 0, y = 1, z = 0})
|
||||
local node = minetest.get_node_or_nil(npos)
|
||||
if node and node.name ~= air then
|
||||
minetest.dig_node(npos)
|
||||
end
|
||||
local velocity = player:get_velocity()
|
||||
velocity.y = 0
|
||||
if vector.length(velocity) < 0.1 then
|
||||
findpath(global_goal)
|
||||
return
|
||||
end
|
||||
local distance = vector.distance(pos, goal)
|
||||
if not next_goal and distance < 1 then
|
||||
index = index + 1
|
||||
end
|
||||
local direction = vector.direction(pos, vector.new(goal.x, 0, goal.z))
|
||||
local yaw = player:get_yaw() % 360
|
||||
local goal_yaw = math.deg(math.atan2(-direction.x, direction.z)) % 360
|
||||
local diff = math.abs(goal_yaw - yaw)
|
||||
if diff > 175 and diff < 185 and distance < 1 then
|
||||
index = index + 1
|
||||
elseif diff > 10 and diff < 350 then
|
||||
if yaw < goal_yaw and diff < 180 or yaw > goal_yaw and diff > 180 then
|
||||
yaw = yaw + 10
|
||||
elseif yaw < goal_yaw and diff > 180 or yaw > goal_yaw and diff < 180 then
|
||||
yaw = yaw - 10
|
||||
end
|
||||
if diff >= 90 and diff <= 270 then
|
||||
minetest.set_keypress("sneak", true)
|
||||
end
|
||||
player:set_yaw(yaw)
|
||||
else
|
||||
player:set_yaw(goal_yaw)
|
||||
end
|
||||
end
|
||||
end)
|
@ -1,3 +0,0 @@
|
||||
name = pathfinding
|
||||
description = Adds the .goto command!
|
||||
author = Fleckenstein
|
@ -1,3 +0,0 @@
|
||||
goto_max_distance (Maximum distance from the search positions to search in) int 25
|
||||
goto_max_jump (Jump height) int 1
|
||||
goto_max_drop (Maximum drop height) int 5
|
@ -1,33 +0,0 @@
|
||||
perlin = dofile(minetest.get_modpath("perlin") .. "/perlin.lua")
|
||||
|
||||
local start, height, stretch
|
||||
|
||||
minetest.register_chatcommand("perlin", {
|
||||
description = "Start perlin terraforming",
|
||||
param = "<height> <stretch>",
|
||||
func = function(param)
|
||||
local sparam = param:split(" ")
|
||||
start, height, stretch = math.floor(minetest.localplayer:get_pos().y), sparam[1], sparam[2]
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("perlinstop", {
|
||||
description = "Abort perlin terraforming",
|
||||
func = function(param)
|
||||
start, height, stretch = nil
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
if start then
|
||||
local player = minetest.localplayer
|
||||
local pos = vector.floor(player:get_pos())
|
||||
for x = pos.x - 1, pos.x + 1 do
|
||||
for z = pos.z - 1, pos.z + 1 do
|
||||
local y = math.floor(start + height * perlin:noise(x / stretch, z / stretch))
|
||||
local p = vector.new(x, y, z)
|
||||
minetest.place_node(p)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
@ -1,3 +0,0 @@
|
||||
name = perlin
|
||||
description = A bot that does terraforming automatically using perlin noise.
|
||||
author = Fleckenstein
|
@ -1,144 +0,0 @@
|
||||
--[[
|
||||
Implemented as described here:
|
||||
http://flafla2.github.io/2014/08/09/perlinnoise.html
|
||||
]]--
|
||||
|
||||
local perlin = {}
|
||||
perlin.p = {}
|
||||
|
||||
local bit32 = {}
|
||||
function bit32.band(a, b)
|
||||
local result = 0
|
||||
local bitval = 1
|
||||
while a > 0 and b > 0 do
|
||||
if a % 2 == 1 and b % 2 == 1 then -- test the rightmost bits
|
||||
result = result + bitval -- set the current bit
|
||||
end
|
||||
bitval = bitval * 2 -- shift left
|
||||
a = math.floor(a/2) -- shift right
|
||||
b = math.floor(b/2)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- Hash lookup table as defined by Ken Perlin
|
||||
-- This is a randomly arranged array of all numbers from 0-255 inclusive
|
||||
local permutation = {151,160,137,91,90,15,
|
||||
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
|
||||
}
|
||||
|
||||
-- p is used to hash unit cube coordinates to [0, 255]
|
||||
for i=0,255 do
|
||||
-- Convert to 0 based index table
|
||||
perlin.p[i] = permutation[i+1]
|
||||
-- Repeat the array to avoid buffer overflow in hash function
|
||||
perlin.p[i+256] = permutation[i+1]
|
||||
end
|
||||
|
||||
-- Return range: [-1, 1]
|
||||
function perlin:noise(x, y, z)
|
||||
y = y or 0
|
||||
z = z or 0
|
||||
|
||||
-- Calculate the "unit cube" that the point asked will be located in
|
||||
local xi = bit32.band(math.floor(x),255)
|
||||
local yi = bit32.band(math.floor(y),255)
|
||||
local zi = bit32.band(math.floor(z),255)
|
||||
|
||||
-- Next we calculate the location (from 0 to 1) in that cube
|
||||
x = x - math.floor(x)
|
||||
y = y - math.floor(y)
|
||||
z = z - math.floor(z)
|
||||
|
||||
-- We also fade the location to smooth the result
|
||||
local u = self.fade(x)
|
||||
local v = self.fade(y)
|
||||
local w = self.fade(z)
|
||||
|
||||
-- Hash all 8 unit cube coordinates surrounding input coordinate
|
||||
local p = self.p
|
||||
local A, AA, AB, AAA, ABA, AAB, ABB, B, BA, BB, BAA, BBA, BAB, BBB
|
||||
A = p[xi ] + yi
|
||||
AA = p[A ] + zi
|
||||
AB = p[A+1 ] + zi
|
||||
AAA = p[ AA ]
|
||||
ABA = p[ AB ]
|
||||
AAB = p[ AA+1 ]
|
||||
ABB = p[ AB+1 ]
|
||||
|
||||
B = p[xi+1] + yi
|
||||
BA = p[B ] + zi
|
||||
BB = p[B+1 ] + zi
|
||||
BAA = p[ BA ]
|
||||
BBA = p[ BB ]
|
||||
BAB = p[ BA+1 ]
|
||||
BBB = p[ BB+1 ]
|
||||
|
||||
-- Take the weighted average between all 8 unit cube coordinates
|
||||
return self.lerp(w,
|
||||
self.lerp(v,
|
||||
self.lerp(u,
|
||||
self:grad(AAA,x,y,z),
|
||||
self:grad(BAA,x-1,y,z)
|
||||
),
|
||||
self.lerp(u,
|
||||
self:grad(ABA,x,y-1,z),
|
||||
self:grad(BBA,x-1,y-1,z)
|
||||
)
|
||||
),
|
||||
self.lerp(v,
|
||||
self.lerp(u,
|
||||
self:grad(AAB,x,y,z-1), self:grad(BAB,x-1,y,z-1)
|
||||
),
|
||||
self.lerp(u,
|
||||
self:grad(ABB,x,y-1,z-1), self:grad(BBB,x-1,y-1,z-1)
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
-- Gradient function finds dot product between pseudorandom gradient vector
|
||||
-- and the vector from input coordinate to a unit cube vertex
|
||||
perlin.dot_product = {
|
||||
[0x0]=function(x,y,z) return x + y end,
|
||||
[0x1]=function(x,y,z) return -x + y end,
|
||||
[0x2]=function(x,y,z) return x - y end,
|
||||
[0x3]=function(x,y,z) return -x - y end,
|
||||
[0x4]=function(x,y,z) return x + z end,
|
||||
[0x5]=function(x,y,z) return -x + z end,
|
||||
[0x6]=function(x,y,z) return x - z end,
|
||||
[0x7]=function(x,y,z) return -x - z end,
|
||||
[0x8]=function(x,y,z) return y + z end,
|
||||
[0x9]=function(x,y,z) return -y + z end,
|
||||
[0xA]=function(x,y,z) return y - z end,
|
||||
[0xB]=function(x,y,z) return -y - z end,
|
||||
[0xC]=function(x,y,z) return y + x end,
|
||||
[0xD]=function(x,y,z) return -y + z end,
|
||||
[0xE]=function(x,y,z) return y - x end,
|
||||
[0xF]=function(x,y,z) return -y - z end
|
||||
}
|
||||
function perlin:grad(hash, x, y, z)
|
||||
return self.dot_product[bit32.band(hash,0xF)](x,y,z)
|
||||
end
|
||||
|
||||
-- Fade function is used to smooth final output
|
||||
function perlin.fade(t)
|
||||
return t * t * t * (t * (t * 6 - 15) + 10)
|
||||
end
|
||||
|
||||
function perlin.lerp(t, a, b)
|
||||
return a + t * (b - a)
|
||||
end
|
||||
|
||||
return perlin
|
@ -1,47 +0,0 @@
|
||||
local warp = warp or {set_here = function() return false end}
|
||||
|
||||
local formspec = ""
|
||||
.. "size[11,5.5]"
|
||||
.. "bgcolor[#320000b4;true]"
|
||||
.. "label[4.85,1.35;" .. "You died" .. "]"
|
||||
.. "button_exit[2,3;3,0.5;btn_respawn;" .. "Respawn" .. "]"
|
||||
.. "button_exit[6,3;3,0.5;btn_ghost_mode;" .. "Ghost Mode" .. "]"
|
||||
.. "set_focus[btn_respawn;true]"
|
||||
|
||||
minetest.register_on_death(function()
|
||||
local warp_success, warp_msg = warp.set_here("death")
|
||||
if warp_success then
|
||||
minetest.display_chat_message(warp_msg)
|
||||
else
|
||||
minetest.display_chat_message("You died at " .. minetest.pos_to_string(minetest.localplayer:get_pos()) .. ".")
|
||||
end
|
||||
if minetest.settings:get_bool("autorespawn") then
|
||||
minetest.send_respawn()
|
||||
else
|
||||
minetest.show_formspec("respawn:death", formspec)
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_formspec_input(function(formname, fields)
|
||||
if formname == "respawn:death" then
|
||||
if fields.btn_ghost_mode then
|
||||
minetest.display_chat_message("You are in ghost mode. Use .respawn to Respawn.")
|
||||
else
|
||||
minetest.send_respawn()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_chatcommand("respawn", {
|
||||
description = "Respawn when in ghost mode",
|
||||
func = function()
|
||||
if minetest.localplayer:get_hp() == 0 then
|
||||
minetest.send_respawn()
|
||||
minetest.display_chat_message("Respawned.")
|
||||
else
|
||||
minetest.display_chat_message("You are not in ghost mode.")
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_cheat("AutoRespawn", "Player", "autorespawn")
|
@ -1,4 +0,0 @@
|
||||
name = respawn
|
||||
author = Fleckenstein
|
||||
description = Extended respawn behaviour
|
||||
optional_depends = warp
|
@ -1 +0,0 @@
|
||||
autorespawn (AutoRespawn) bool false
|
@ -1,204 +0,0 @@
|
||||
local autoeat = rawget(_G, "autoeat") or {}
|
||||
local storage = minetest.get_mod_storage()
|
||||
local pos1, pos2
|
||||
local min, max = math.min, math.max
|
||||
local building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks
|
||||
|
||||
minetest.register_chatcommand("pos1", {
|
||||
description = "Set schematicas position 1 at your current location",
|
||||
func = function()
|
||||
pos1 = vector.round(minetest.localplayer:get_pos())
|
||||
return true, "Position 1 set to " .. minetest.pos_to_string(pos1)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("pos2", {
|
||||
description = "Set schematicas position 2 at your current location",
|
||||
func = function()
|
||||
pos2 = vector.round(minetest.localplayer:get_pos())
|
||||
return true, "Position 2 set to " .. minetest.pos_to_string(pos2)
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("schemesave", {
|
||||
description = "Save a schematica",
|
||||
param = "<name>",
|
||||
func = function(name)
|
||||
if not pos1 or not pos2 then
|
||||
return false, "Position 1 or 2 not set."
|
||||
end
|
||||
|
||||
local data = {}
|
||||
|
||||
local lx, ly, lz, hx, hy, hz = min(pos1.x, pos2.x), min(pos1.y, pos2.y), min(pos1.z, pos2.z), max(pos1.x, pos2.x), max(pos1.y, pos2.y), max(pos1.z, pos2.z)
|
||||
|
||||
for x = lx, hx do
|
||||
local rx = x - lx
|
||||
for y = ly, hy do
|
||||
local ry = y - ly
|
||||
for z = lz, hz do
|
||||
local rz = z - lz
|
||||
local node = minetest.get_node_or_nil({x = x, y = y, z = z})
|
||||
if node and node.name ~= "air" then
|
||||
table.insert(data, {pos = {x = rx, y = ry, z = rz}, node = node.name})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
storage:set_string(name, minetest.serialize(data))
|
||||
return true, "Scheme saved successfully as '" .. name .. "'."
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemebuild", {
|
||||
description = "Build a schematica",
|
||||
param = "<name>",
|
||||
func = function(name)
|
||||
if not pos1 then
|
||||
return false, "Position 1 not set."
|
||||
end
|
||||
if building then
|
||||
return false, "Still building a scheme. Use .schemeabort to stop it."
|
||||
end
|
||||
local rawdata = storage:get(name)
|
||||
if not rawdata then
|
||||
return false, "Schematica '" .. name .. "' not found."
|
||||
end
|
||||
building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = true, 1, minetest.deserialize(rawdata), vector.new(pos1), false, 0, false
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemerecipe", {
|
||||
description = "Print the recipe for a schematica",
|
||||
param = "<name>",
|
||||
func = function(name)
|
||||
local rawdata = storage:get(name)
|
||||
if not rawdata then
|
||||
return false, "Schematica '" .. name .. "' not found."
|
||||
end
|
||||
local data = minetest.deserialize(rawdata)
|
||||
local sorted = {}
|
||||
for _, d in ipairs(data) do
|
||||
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemeresume", {
|
||||
description = "Resume constructing a schematica",
|
||||
func = function()
|
||||
if not build_data then
|
||||
return false, "Currently not building a scheme."
|
||||
end
|
||||
building, out_of_blocks = true, false
|
||||
return true, "Resumed."
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemepause", {
|
||||
description = "Pause constructing a schematica",
|
||||
func = function()
|
||||
if not build_data then
|
||||
return false, "Currently not building a scheme."
|
||||
end
|
||||
building = false
|
||||
return true, "Paused."
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemeabort", {
|
||||
description = "Abort constructing a schematica",
|
||||
param = "<name>",
|
||||
func = function()
|
||||
if not build_data then
|
||||
return false, "Currently not building a scheme."
|
||||
end
|
||||
building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nilw
|
||||
return true, "Aborted."
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemeskip", {
|
||||
description = "Skip a step in constructing a schematica",
|
||||
param = "<name>",
|
||||
func = function()
|
||||
if not build_data then
|
||||
return false, "Currently not building a scheme."
|
||||
end
|
||||
building, build_index = true, build_index + 1
|
||||
return true, "Skipped."
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemegetindex", {
|
||||
description = "Output the build index of the schematica",
|
||||
func = function()
|
||||
return build_index and true or false, build_index
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("schemesetindex", {
|
||||
description = "Set the build index of the schematica",
|
||||
param = "<index>",
|
||||
func = function(param)
|
||||
local index = tonumber(param)
|
||||
if not index then return false, "Invalid usage." end
|
||||
build_index = index
|
||||
return true, "Index Changed"
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
if building and not autoeat.eating then
|
||||
local data = build_data[build_index]
|
||||
if not data then
|
||||
building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nil
|
||||
minetest.display_chat_message("Completed Schematica.")
|
||||
return
|
||||
end
|
||||
local pos, node = vector.add(build_pos, data.pos), data.node
|
||||
if just_placed_node then
|
||||
local map_node = minetest.get_node_or_nil(pos)
|
||||
if map_node and map_node.name == node then
|
||||
build_index = build_index + 1
|
||||
just_placed_node = false
|
||||
else
|
||||
failed_count = failed_count + 1
|
||||
end
|
||||
if failed_count < 10 then
|
||||
return
|
||||
end
|
||||
end
|
||||
failed_count = 0
|
||||
local new_index
|
||||
local inventory = minetest.get_inventory("current_player").main
|
||||
for index, stack in ipairs(inventory) do
|
||||
if minetest.get_item_def(stack:get_name()).node_placement_prediction == node then
|
||||
new_index = index - 1
|
||||
break
|
||||
end
|
||||
end
|
||||
if not new_index then
|
||||
if not out_of_blocks then
|
||||
minetest.display_chat_message("Out of blocks for schematica. Missing ressource: '" .. node .. "'. It will resume as soon as you got it or use .schemeskip to skip it.")
|
||||
minetest.send_chat_message("[Schematicas] Missing ressource: " .. node)
|
||||
end
|
||||
out_of_blocks = true
|
||||
return
|
||||
end
|
||||
if out_of_blocks then
|
||||
minetest.send_chat_message("[Schematicas] Resuming.")
|
||||
end
|
||||
out_of_blocks = false
|
||||
minetest.localplayer:set_wield_index(new_index)
|
||||
minetest.localplayer:set_pos(minetest.find_node_near(pos, 5, {"air", "ignore", "mcl_core:water_source", "mcl_core:water_flowing"}, false) or pos)
|
||||
minetest.place_node(pos)
|
||||
just_placed_node = true
|
||||
if build_index % 250 == 0 then
|
||||
minetest.send_chat_message("[Schematicas] " .. build_index .. " of " .. #build_data .. " blocks placed!")
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
@ -1,4 +0,0 @@
|
||||
name = schematicas
|
||||
description = Save structures and recreate them automatically in survival.
|
||||
author = Fleckenstein
|
||||
optional_depends = autoeat
|
@ -1,94 +0,0 @@
|
||||
warp = {}
|
||||
|
||||
local storage = minetest.get_mod_storage()
|
||||
|
||||
function warp.set(warp, pos)
|
||||
if warp == "" or not pos then return false, "Missing parameter." end
|
||||
local posstr = minetest.pos_to_string(pos)
|
||||
storage:set_string(warp, posstr)
|
||||
return true, "Warp " .. warp .. " set to " .. posstr .. "."
|
||||
end
|
||||
|
||||
function warp.set_here(param)
|
||||
local success, message = warp.set(param, vector.round(minetest.localplayer:get_pos()))
|
||||
return success, message
|
||||
end
|
||||
|
||||
function warp.get(param)
|
||||
if param == "" then return false, "Missing parameter." end
|
||||
local pos = storage:get_string(param)
|
||||
if pos == "" then return false, "Warp " .. param .. " not set." end
|
||||
return true, "Warp " .. param .. " is set to " .. pos .. ".", minetest.string_to_pos(pos)
|
||||
end
|
||||
|
||||
function warp.delete(param)
|
||||
if param == "" then return false, "Missing parameter." end
|
||||
storage:set_string(param, "")
|
||||
return true, "Deleted warp " .. param .. "."
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("setwarp", {
|
||||
params = "<warp>",
|
||||
description = "Set a warp to your current position.",
|
||||
func = warp.set_here,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("readwarp", {
|
||||
params = "<warp>",
|
||||
description = "Print the coordinates of a warp.",
|
||||
func = warp.get,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("deletewarp", {
|
||||
params = "<warp>",
|
||||
description = "Delete a warp.",
|
||||
func = warp.delete,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("listwarps", {
|
||||
description = "List all warps.",
|
||||
func = function()
|
||||
local warps = storage:to_table().fields
|
||||
local warplist = {}
|
||||
for warp in pairs(warps) do
|
||||
table.insert(warplist, warp)
|
||||
end
|
||||
if #warplist > 0 then
|
||||
return true, table.concat(warplist, ", ")
|
||||
else
|
||||
return false, "No warps set."
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
local function do_warp(param)
|
||||
if param == "" then return false, "Missing parameter." end
|
||||
local success, pos = minetest.parse_pos(param)
|
||||
if not success then
|
||||
local msg
|
||||
success, msg, pos = warp.get(param)
|
||||
if not success then
|
||||
return false, msg
|
||||
end
|
||||
end
|
||||
minetest.localplayer:set_pos(pos)
|
||||
return true, "Warped to " .. minetest.pos_to_string(pos)
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("warp", {
|
||||
params = "<pos>|<warp>",
|
||||
description = "Warp to a set warp or a position.",
|
||||
func = do_warp
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("warpandexit", {
|
||||
params = "<pos>|<warp>",
|
||||
description = "Warp to a set warp or a position and exit.",
|
||||
func = function(param)
|
||||
local s, m = do_warp(param)
|
||||
if s then
|
||||
minetest.disconnect()
|
||||
end
|
||||
return s,m
|
||||
end
|
||||
})
|
@ -1,3 +0,0 @@
|
||||
name = warp
|
||||
author = Fleckenstein
|
||||
description = Set custom warps and use the teleport exploit
|
@ -1,97 +0,0 @@
|
||||
minetest.register_chatcommand("findnodes", {
|
||||
description = "Scan for one or multible nodes in a radius around you",
|
||||
param = "<radius> <node1>[,<node2>...]",
|
||||
func = function(param)
|
||||
local radius = tonumber(param:split(" ")[1])
|
||||
local nodes = param:split(" ")[2]:split(",")
|
||||
local pos = minetest.localplayer:get_pos()
|
||||
local fpos = minetest.find_node_near(pos, radius, nodes, true)
|
||||
if fpos then
|
||||
return true, "Found " .. table.concat(nodes, " or ") .. " at " .. minetest.pos_to_string(fpos)
|
||||
end
|
||||
return false, "None of " .. table.concat(nodes, " or ") .. " found in a radius of " .. tostring(radius)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("place", {
|
||||
params = "<X>,<Y>,<Z>",
|
||||
description = "Place wielded item",
|
||||
func = function(param)
|
||||
local success, pos = minetest.parse_relative_pos(param)
|
||||
if success then
|
||||
minetest.place_node(pos)
|
||||
return true, "Node placed at " .. minetest.pos_to_string(pos)
|
||||
end
|
||||
return false, pos
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("dig", {
|
||||
params = "<X>,<Y>,<Z>",
|
||||
description = "Dig node",
|
||||
func = function(param)
|
||||
local success, pos = minetest.parse_relative_pos(param)
|
||||
if success then
|
||||
minetest.dig_node(pos)
|
||||
return true, "Node at " .. minetest.pos_to_string(pos) .. " dug"
|
||||
end
|
||||
return false, pos
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_on_dignode(function(pos)
|
||||
if minetest.settings:get_bool("replace") then
|
||||
minetest.after(0, minetest.place_node, pos)
|
||||
end
|
||||
end)
|
||||
|
||||
local etime = 0
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
etime = etime + dtime
|
||||
if etime < 1 then return end
|
||||
local player = minetest.localplayer
|
||||
if not player then return end
|
||||
local pos = player:get_pos()
|
||||
local item = player:get_wielded_item()
|
||||
local def = minetest.get_item_def(item:get_name())
|
||||
local nodes_per_tick = tonumber(minetest.settings:get("nodes_per_tick")) or 8
|
||||
if item and item:get_count() > 0 and def and def.node_placement_prediction ~= "" then
|
||||
if minetest.settings:get_bool("scaffold") then
|
||||
minetest.place_node(vector.add(pos, {x = 0, y = -0.6, z = 0}))
|
||||
elseif minetest.settings:get_bool("highway_z") then
|
||||
local z = pos.z
|
||||
local positions = {
|
||||
{x = 0, y = 0, z = z},
|
||||
{x = 1, y = 0, z = z},
|
||||
{x = 2, y = 1, z = z},
|
||||
{x = -2, y = 1, z = z},
|
||||
{x = -2, y = 0, z = z},
|
||||
{x = -1, y = 0, z = z},
|
||||
{x = 2, y = 0, z = z}
|
||||
}
|
||||
for i, p in pairs(positions) do
|
||||
if i > nodes_per_tick then break end
|
||||
minetest.place_node(p)
|
||||
end
|
||||
elseif minetest.settings:get_bool("block_water") then
|
||||
local positions = minetest.find_nodes_near(pos, 5, {"mcl_core:water_source", "mcl_core:water_floating"}, true)
|
||||
for i, p in pairs(positions) do
|
||||
if i > nodes_per_tick then break end
|
||||
minetest.place_node(p)
|
||||
end
|
||||
elseif minetest.settings:get_bool("autotnt") then
|
||||
local positions = minetest.find_nodes_near_under_air_except(pos, 5, item:get_name(), true)
|
||||
for i, p in pairs(positions) do
|
||||
if i > nodes_per_tick then break end
|
||||
minetest.place_node(vector.add(p, {x = 0, y = 1, z = 0}))
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_cheat("Scaffold", "World", "scaffold")
|
||||
minetest.register_cheat("HighwayZ", "World", "highway_z")
|
||||
minetest.register_cheat("BlockWater", "World", "block_water")
|
||||
minetest.register_cheat("AutoTNT", "World", "autotnt")
|
||||
minetest.register_cheat("Replace", "World", "replace")
|
@ -1,3 +0,0 @@
|
||||
name = world
|
||||
desciption = Adds several world interaction bots to dragonfire.
|
||||
author = Fleckenstein
|
@ -1,6 +0,0 @@
|
||||
scaffold (Scaffold) bool false
|
||||
highway_z (HighwayZ) bool false
|
||||
block_water (BlockWater) bool false
|
||||
autotnt (AutoTNT) bool false
|
||||
replace (Replace) bool false
|
||||
nodes_per_tick (Number of nodes to place per tick) int 8
|
@ -1,12 +0,0 @@
|
||||
load_mod_warp = true
|
||||
load_mod_world = true
|
||||
load_mod_respawn = true
|
||||
load_mod_inventory = true
|
||||
load_mod_commands = true
|
||||
load_mod_chat = true
|
||||
load_mod_schematicas = true
|
||||
load_mod_pathfinding = true
|
||||
load_mod_autoeat = true
|
||||
load_mod_perlin = true
|
||||
load_mod_autosneak = true
|
||||
load_mod_list = true
|
@ -1480,6 +1480,8 @@ The following functions provide escape sequences:
|
||||
`minetest.get_color_escape_sequence(color) ..
|
||||
message ..
|
||||
minetest.get_color_escape_sequence("#ffffff")`
|
||||
* `minetest.rainbow(message)`:
|
||||
* Rainbow colorizes the message.
|
||||
* `minetest.get_background_escape_sequence(color)`
|
||||
* `color` is a [ColorString](#colorstring)
|
||||
* The escape sequence sets the background of the whole text element to
|
||||
|
@ -2988,6 +2988,8 @@ The following functions provide escape sequences:
|
||||
`minetest.get_color_escape_sequence(color) ..
|
||||
message ..
|
||||
minetest.get_color_escape_sequence("#ffffff")`
|
||||
* `minetest.rainbow(message)`:
|
||||
* Rainbow colorizes the message.
|
||||
* `minetest.get_background_escape_sequence(color)`
|
||||
* `color` is a ColorString
|
||||
* The escape sequence sets the background of the whole text element to
|
||||
|
@ -1071,8 +1071,8 @@ void Game::processKeyInput()
|
||||
toggleAutoforward();
|
||||
} else if (wasKeyDown(KeyType::INVENTORY)) {
|
||||
openInventory();
|
||||
} else if (wasKeyDown(KeyType::SPECIAL_INVENTORY)) {
|
||||
openSpecialInventory();
|
||||
} else if (wasKeyDown(KeyType::ENDERCHEST)) {
|
||||
openEnderchest();
|
||||
} else if (input->cancelPressed()) {
|
||||
#ifdef __ANDROID__
|
||||
m_android_chat_open = false;
|
||||
@ -1105,6 +1105,10 @@ void Game::processKeyInput()
|
||||
toggleKillaura();
|
||||
} else if (wasKeyDown(KeyType::FREECAM)) {
|
||||
toggleFreecam();
|
||||
} else if (wasKeyDown(KeyType::SCAFFOLD)) {
|
||||
toggleScaffold();
|
||||
} else if (wasKeyDown(KeyType::NEXT_ITEM)) {
|
||||
toggleNextItem();
|
||||
} else if (wasKeyDown(KeyType::SELECT_UP)) {
|
||||
m_cheat_menu->selectUp();
|
||||
} else if (wasKeyDown(KeyType::SELECT_DOWN)) {
|
||||
@ -1285,7 +1289,7 @@ void Game::openInventory()
|
||||
}
|
||||
}
|
||||
|
||||
void Game::openSpecialInventory()
|
||||
void Game::openEnderchest()
|
||||
{
|
||||
LocalPlayer *player = client->getEnv().getLocalPlayer();
|
||||
if (!player || !player->getCAO())
|
||||
@ -1294,7 +1298,7 @@ void Game::openSpecialInventory()
|
||||
infostream << "Game: Launching special inventory" << std::endl;
|
||||
|
||||
if (client->modsLoaded())
|
||||
client->getScript()->open_special_inventory();
|
||||
client->getScript()->open_enderchest();
|
||||
}
|
||||
|
||||
|
||||
@ -1428,6 +1432,30 @@ void Game::toggleFreecam()
|
||||
}
|
||||
}
|
||||
|
||||
void Game::toggleScaffold()
|
||||
{
|
||||
bool scaffold = ! g_settings->getBool("scaffold");
|
||||
g_settings->set("scaffold", bool_to_cstr(scaffold));
|
||||
|
||||
if (scaffold) {
|
||||
m_game_ui->showTranslatedStatusText("Scaffold enabled");
|
||||
} else {
|
||||
m_game_ui->showTranslatedStatusText("Scaffold disabled");
|
||||
}
|
||||
}
|
||||
|
||||
void Game::toggleNextItem()
|
||||
{
|
||||
bool next_item = ! g_settings->getBool("next_item");
|
||||
g_settings->set("next_item", bool_to_cstr(next_item));
|
||||
|
||||
if (next_item) {
|
||||
m_game_ui->showTranslatedStatusText("NextItem enabled");
|
||||
} else {
|
||||
m_game_ui->showTranslatedStatusText("NextItem disabled");
|
||||
}
|
||||
}
|
||||
|
||||
void Game::toggleCinematic()
|
||||
{
|
||||
bool cinematic = !g_settings->getBool("cinematic");
|
||||
@ -3432,7 +3460,7 @@ void Game::showPauseMenu()
|
||||
"- %s: sneak/go down\n"
|
||||
"- %s: drop item\n"
|
||||
"- %s: inventory\n"
|
||||
"- %s: special inventory\n"
|
||||
"- %s: enderchest\n"
|
||||
"- Mouse: turn/look\n"
|
||||
"- Mouse left: dig/punch\n"
|
||||
"- Mouse right: place/use\n"
|
||||
@ -3440,6 +3468,8 @@ void Game::showPauseMenu()
|
||||
"- %s: chat\n"
|
||||
"- %s: Killaura\n"
|
||||
"- %s: Freecam\n"
|
||||
"- %s: Scaffold\n"
|
||||
"- %s: NextItem\n"
|
||||
);
|
||||
|
||||
char control_text_buf[600];
|
||||
@ -3453,10 +3483,12 @@ void Game::showPauseMenu()
|
||||
GET_KEY_NAME(keymap_sneak),
|
||||
GET_KEY_NAME(keymap_drop),
|
||||
GET_KEY_NAME(keymap_inventory),
|
||||
GET_KEY_NAME(keymap_special_inventory),
|
||||
GET_KEY_NAME(keymap_enderchest),
|
||||
GET_KEY_NAME(keymap_chat),
|
||||
GET_KEY_NAME(keymap_toggle_killaura),
|
||||
GET_KEY_NAME(keymap_toggle_freecam)
|
||||
GET_KEY_NAME(keymap_toggle_freecam),
|
||||
GET_KEY_NAME(keymap_toggle_scaffold),
|
||||
GET_KEY_NAME(keymap_toggle_next_item)
|
||||
);
|
||||
|
||||
std::string control_text = std::string(control_text_buf);
|
||||
|
@ -724,7 +724,7 @@ public:
|
||||
|
||||
void dropSelectedItem(bool single_item = false);
|
||||
void openInventory();
|
||||
void openSpecialInventory();
|
||||
void openEnderchest();
|
||||
void openConsole(float scale, const wchar_t *line=NULL);
|
||||
void toggleFreeMove();
|
||||
void toggleFreeMoveAlt();
|
||||
@ -733,6 +733,8 @@ public:
|
||||
void toggleNoClip();
|
||||
void toggleKillaura();
|
||||
void toggleFreecam();
|
||||
void toggleScaffold();
|
||||
void toggleNextItem();
|
||||
void toggleCinematic();
|
||||
void toggleAutoforward();
|
||||
|
||||
|
@ -42,7 +42,7 @@ void KeyCache::populate()
|
||||
|
||||
key[KeyType::DROP] = getKeySetting("keymap_drop");
|
||||
key[KeyType::INVENTORY] = getKeySetting("keymap_inventory");
|
||||
key[KeyType::SPECIAL_INVENTORY] = getKeySetting("keymap_special_inventory");
|
||||
key[KeyType::ENDERCHEST] = getKeySetting("keymap_enderchest");
|
||||
key[KeyType::CHAT] = getKeySetting("keymap_chat");
|
||||
key[KeyType::CMD] = getKeySetting("keymap_cmd");
|
||||
key[KeyType::CMD_LOCAL] = getKeySetting("keymap_cmd_local");
|
||||
@ -75,6 +75,8 @@ void KeyCache::populate()
|
||||
key[KeyType::ZOOM] = getKeySetting("keymap_zoom");
|
||||
key[KeyType::KILLAURA] = getKeySetting("keymap_toggle_killaura");
|
||||
key[KeyType::FREECAM] = getKeySetting("keymap_toggle_freecam");
|
||||
key[KeyType::SCAFFOLD] = getKeySetting("keymap_toggle_scaffold");
|
||||
key[KeyType::NEXT_ITEM] = getKeySetting("keymap_toggle_next_item");
|
||||
key[KeyType::SELECT_UP] = getKeySetting("keymap_select_up");
|
||||
key[KeyType::SELECT_DOWN] = getKeySetting("keymap_select_down");
|
||||
key[KeyType::SELECT_LEFT] = getKeySetting("keymap_select_left");
|
||||
|
@ -41,7 +41,7 @@ public:
|
||||
// Other
|
||||
DROP,
|
||||
INVENTORY,
|
||||
SPECIAL_INVENTORY,
|
||||
ENDERCHEST,
|
||||
CHAT,
|
||||
CMD,
|
||||
CMD_LOCAL,
|
||||
@ -72,6 +72,8 @@ public:
|
||||
ZOOM,
|
||||
KILLAURA,
|
||||
FREECAM,
|
||||
SCAFFOLD,
|
||||
NEXT_ITEM,
|
||||
SELECT_UP,
|
||||
SELECT_DOWN,
|
||||
SELECT_LEFT,
|
||||
|
@ -69,7 +69,7 @@ void RenderingCore::draw(video::SColor _skycolor, bool _show_hud, bool _show_min
|
||||
draw_crosshair = _draw_crosshair;
|
||||
draw_tracers = _draw_tracers;
|
||||
draw_esp = _draw_esp;
|
||||
|
||||
|
||||
beforeDraw();
|
||||
drawAll();
|
||||
}
|
||||
|
@ -95,7 +95,20 @@ void set_default_settings(Settings *settings)
|
||||
settings->setDefault("enable_esp", "false");
|
||||
settings->setDefault("no_slow", "false");
|
||||
settings->setDefault("float_above_parent", "false");
|
||||
|
||||
settings->setDefault("ignore_status_messages", "true");
|
||||
settings->setDefault("mark_deathmessages", "true");
|
||||
settings->setDefault("autosneak", "false");
|
||||
settings->setDefault("autoeject", "false");
|
||||
settings->setDefault("eject_items", "");
|
||||
settings->setDefault("autotool", "false");
|
||||
settings->setDefault("autorespawn", "false");
|
||||
settings->setDefault("next_item", "false");
|
||||
settings->setDefault("scaffold", "false");
|
||||
settings->setDefault("scaffold_plus", "false");
|
||||
settings->setDefault("block_water", "false");
|
||||
settings->setDefault("autotnt", "false");
|
||||
settings->setDefault("replace", "false");
|
||||
|
||||
// Keymap
|
||||
settings->setDefault("remote_port", "30000");
|
||||
settings->setDefault("keymap_forward", "KEY_KEY_W");
|
||||
@ -108,7 +121,7 @@ void set_default_settings(Settings *settings)
|
||||
settings->setDefault("keymap_drop", "KEY_KEY_Q");
|
||||
settings->setDefault("keymap_zoom", "KEY_KEY_Z");
|
||||
settings->setDefault("keymap_inventory", "KEY_KEY_I");
|
||||
settings->setDefault("keymap_special_inventory", "KEY_KEY_O");
|
||||
settings->setDefault("keymap_enderchest", "KEY_KEY_O");
|
||||
settings->setDefault("keymap_special1", "KEY_KEY_E");
|
||||
settings->setDefault("keymap_chat", "KEY_KEY_T");
|
||||
settings->setDefault("keymap_cmd", "/");
|
||||
@ -143,6 +156,8 @@ void set_default_settings(Settings *settings)
|
||||
settings->setDefault("keymap_decrease_viewing_range_min", "-");
|
||||
settings->setDefault("keymap_toggle_killaura", "KEY_KEY_X");
|
||||
settings->setDefault("keymap_toggle_freecam", "KEY_KEY_G");
|
||||
settings->setDefault("keymap_toggle_scaffold", "KEY_KEY_Y");
|
||||
settings->setDefault("keymap_toggle_next_item", "KEY_KEY_U");
|
||||
settings->setDefault("keymap_select_up", "KEY_UP");
|
||||
settings->setDefault("keymap_select_down", "KEY_DOWN");
|
||||
settings->setDefault("keymap_select_left", "KEY_LEFT");
|
||||
|
@ -59,7 +59,7 @@ enum
|
||||
GUI_ID_KEY_SNEAK_BUTTON,
|
||||
GUI_ID_KEY_DROP_BUTTON,
|
||||
GUI_ID_KEY_INVENTORY_BUTTON,
|
||||
GUI_ID_KEY_SPECIAL_INVENTORY_BUTTON,
|
||||
GUI_ID_KEY_ENDERCHEST_BUTTON,
|
||||
GUI_ID_KEY_HOTBAR_PREV_BUTTON,
|
||||
GUI_ID_KEY_HOTBAR_NEXT_BUTTON,
|
||||
GUI_ID_KEY_MUTE_BUTTON,
|
||||
@ -79,6 +79,8 @@ enum
|
||||
GUI_ID_KEY_AUTOFWD_BUTTON,
|
||||
GUI_ID_KEY_KILLAURA_BUTTON,
|
||||
GUI_ID_KEY_FREECAM_BUTTON,
|
||||
GUI_ID_KEY_SCAFFOLD_BUTTON,
|
||||
GUI_ID_KEY_NEXT_ITEM_BUTTON,
|
||||
GUI_ID_KEY_SELECT_UP_BUTTON,
|
||||
GUI_ID_KEY_SELECT_DOWN_BUTTON,
|
||||
GUI_ID_KEY_SELECT_LEFT_BUTTON,
|
||||
@ -430,7 +432,7 @@ void GUIKeyChangeMenu::init_keys()
|
||||
this->add_key(GUI_ID_KEY_SNEAK_BUTTON, wgettext("Sneak"), "keymap_sneak");
|
||||
this->add_key(GUI_ID_KEY_DROP_BUTTON, wgettext("Drop"), "keymap_drop");
|
||||
this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, wgettext("Inventory"), "keymap_inventory");
|
||||
this->add_key(GUI_ID_KEY_SPECIAL_INVENTORY_BUTTON,wgettext("Special Inv."),"keymap_special_inventory");
|
||||
this->add_key(GUI_ID_KEY_ENDERCHEST_BUTTON,wgettext("Enderchest"), "keymap_enderchest");
|
||||
this->add_key(GUI_ID_KEY_HOTBAR_PREV_BUTTON,wgettext("Prev. item"), "keymap_hotbar_previous");
|
||||
this->add_key(GUI_ID_KEY_HOTBAR_NEXT_BUTTON,wgettext("Next item"), "keymap_hotbar_next");
|
||||
this->add_key(GUI_ID_KEY_ZOOM_BUTTON, wgettext("Zoom"), "keymap_zoom");
|
||||
@ -456,8 +458,10 @@ void GUIKeyChangeMenu::init_keys()
|
||||
this->add_key(GUI_ID_KEY_CHATLOG_BUTTON, wgettext("Toggle chat log"), "keymap_toggle_chat");
|
||||
this->add_key(GUI_ID_KEY_FOG_BUTTON, wgettext("Toggle fog"), "keymap_toggle_fog");
|
||||
this->add_key(GUI_ID_KEY_CHEAT_MENU_BUTTON,wgettext("Toggle C. Menu"),"keymap_toggle_cheat_menu");
|
||||
this->add_key(GUI_ID_KEY_KILLAURA_BUTTON, wgettext("Toggle Killaura"), "keymap_toggle_killaura");
|
||||
this->add_key(GUI_ID_KEY_FREECAM_BUTTON, wgettext("Toggle Freec."), "keymap_toggle_freecam");
|
||||
this->add_key(GUI_ID_KEY_KILLAURA_BUTTON, wgettext("Killaura"), "keymap_toggle_killaura");
|
||||
this->add_key(GUI_ID_KEY_FREECAM_BUTTON, wgettext("Freecam"), "keymap_toggle_freecam");
|
||||
this->add_key(GUI_ID_KEY_SCAFFOLD_BUTTON, wgettext("Scaffold"), "keymap_toggle_scaffold");
|
||||
this->add_key(GUI_ID_KEY_NEXT_ITEM_BUTTON, wgettext("NextItem"), "keymap_toggle_next_item");
|
||||
this->add_key(GUI_ID_KEY_SELECT_UP_BUTTON, wgettext("C. Menu Up"), "keymap_select_up");
|
||||
this->add_key(GUI_ID_KEY_SELECT_DOWN_BUTTON,wgettext("C. Menu Down"), "keymap_select_down");
|
||||
this->add_key(GUI_ID_KEY_SELECT_LEFT_BUTTON,wgettext("C. Menu Left"), "keymap_select_left");
|
||||
|
@ -234,7 +234,7 @@ bool ScriptApiClient::on_inventory_open(Inventory *inventory)
|
||||
return readParam<bool>(L, -1);
|
||||
}
|
||||
|
||||
void ScriptApiClient::open_special_inventory()
|
||||
void ScriptApiClient::open_enderchest()
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
@ -243,7 +243,7 @@ void ScriptApiClient::open_special_inventory()
|
||||
lua_insert(L, error_handler);
|
||||
|
||||
lua_getglobal(L, "core");
|
||||
lua_getfield(L, -1, "open_special_inventory");
|
||||
lua_getfield(L, -1, "open_enderchest");
|
||||
if (lua_isfunction(L, -1))
|
||||
lua_pcall(L, 0, 0, error_handler);
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
bool on_item_use(const ItemStack &item, const PointedThing &pointed);
|
||||
|
||||
bool on_inventory_open(Inventory *inventory);
|
||||
void open_special_inventory();
|
||||
void open_enderchest();
|
||||
|
||||
void setEnv(ClientEnvironment *env);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user