diff --git a/builtin/client/cheats.lua b/builtin/client/cheats.lua index 839021ad2..db6cc15cb 100644 --- a/builtin/client/cheats.lua +++ b/builtin/client/cheats.lua @@ -2,16 +2,16 @@ core.cheats = { ["Combat"] = { ["Killaura"] = "killaura", ["AntiKnockback"] = "antiknockback", - ["NoFallDamage"] = "prevent_natural_damage", + ["FastHit"] = "spamclick", }, ["Movement"] = { - ["GodMode"] = "entity_speed", ["Freecam"] = "freecam", ["PrivBypass"] = "priv_bypass", ["AutoForward"] = "continuous_forward", ["PitchMove"] = "pitch_move", ["AutoJump"] = "autojump", ["Jesus"] = "jesus", + ["NoSlow"] = "no_slow", }, ["Render"] = { ["Xray"] = "xray", @@ -20,7 +20,7 @@ core.cheats = { ["NoHurtCam"] = "no_hurt_cam", ["BrightNight"] = "no_night", ["Coords"] = "coords", - ["Clouds"] = "enable_clouds", + ["Tracers"] = "enable_tracers", }, ["World"] = { ["FastDig"] = "fastdig", @@ -32,6 +32,14 @@ core.cheats = { ["UnlimitedRange"] = "increase_tool_range_plus", ["PointLiquids"] = "point_liquids", }, + ["Exploit"] = { + ["EntitySpeed"] = "entity_speed", + ["ParticleExploit"] = "log_particles", + }, + ["Player"] = { + ["NoFallDamage"] = "prevent_natural_damage", + ["NoForceRotate"] = "no_force_rotate", + }, } function core.register_cheat(cheatname, category, func) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index e076ac2ea..8452850fa 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -2262,3 +2262,13 @@ no_night (BrightNight) bool false coords (Coords) bool false point_liquids (PointLiquids) bool false + +log_particles (ParticleExploit) bool false + +spamclick (FastHit) bool false + +no_force_rotate (NoForceRotate) bool false + +enable_tracers (Tracers) bool false + +no_slow (NoSlow) bool false diff --git a/clientmods/dragonfire/autoeat/init.lua b/clientmods/dragonfire/autoeat/init.lua new file mode 100644 index 000000000..7435e1796 --- /dev/null +++ b/clientmods/dragonfire/autoeat/init.lua @@ -0,0 +1,21 @@ +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") diff --git a/clientmods/dragonfire/autoeat/mod.conf b/clientmods/dragonfire/autoeat/mod.conf new file mode 100644 index 000000000..d6dc9dbc4 --- /dev/null +++ b/clientmods/dragonfire/autoeat/mod.conf @@ -0,0 +1,3 @@ +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 diff --git a/clientmods/dragonfire/autoeat/settingtypes.txt b/clientmods/dragonfire/autoeat/settingtypes.txt new file mode 100644 index 000000000..9614de087 --- /dev/null +++ b/clientmods/dragonfire/autoeat/settingtypes.txt @@ -0,0 +1 @@ +autoeat (Automatically eat when damage was taken) bool false diff --git a/clientmods/dragonfire/chat/colors.lua b/clientmods/dragonfire/chat/colors.lua new file mode 100644 index 000000000..b3ab596fb --- /dev/null +++ b/clientmods/dragonfire/chat/colors.lua @@ -0,0 +1,33 @@ +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) + diff --git a/clientmods/dragonfire/chat/init.lua b/clientmods/dragonfire/chat/init.lua new file mode 100644 index 000000000..5086bc570 --- /dev/null +++ b/clientmods/dragonfire/chat/init.lua @@ -0,0 +1,13 @@ +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") + + diff --git a/clientmods/dragonfire/chat/leak.lua b/clientmods/dragonfire/chat/leak.lua new file mode 100644 index 000000000..a11704d55 --- /dev/null +++ b/clientmods/dragonfire/chat/leak.lua @@ -0,0 +1,10 @@ +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) diff --git a/clientmods/dragonfire/chat/mod.conf b/clientmods/dragonfire/chat/mod.conf new file mode 100644 index 000000000..ce94dc1bc --- /dev/null +++ b/clientmods/dragonfire/chat/mod.conf @@ -0,0 +1,3 @@ +name = chat +author = Fleckenstein +description = The chat modifications of Dragonfireclient diff --git a/clientmods/dragonfire/chat/rainbow.lua b/clientmods/dragonfire/chat/rainbow.lua new file mode 100644 index 000000000..1519619a7 --- /dev/null +++ b/clientmods/dragonfire/chat/rainbow.lua @@ -0,0 +1,61 @@ +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 diff --git a/clientmods/dragonfire/chat/settingtypes.txt b/clientmods/dragonfire/chat/settingtypes.txt new file mode 100644 index 000000000..9428dd955 --- /dev/null +++ b/clientmods/dragonfire/chat/settingtypes.txt @@ -0,0 +1,6 @@ +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 diff --git a/clientmods/dragonfire/chat/spam.lua b/clientmods/dragonfire/chat/spam.lua new file mode 100644 index 000000000..991846d33 --- /dev/null +++ b/clientmods/dragonfire/chat/spam.lua @@ -0,0 +1,12 @@ +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) diff --git a/clientmods/dragonfire/chat/status.lua b/clientmods/dragonfire/chat/status.lua new file mode 100644 index 000000000..4cf56a09e --- /dev/null +++ b/clientmods/dragonfire/chat/status.lua @@ -0,0 +1,5 @@ +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) diff --git a/clientmods/dragonfire/commands/init.lua b/clientmods/dragonfire/commands/init.lua new file mode 100644 index 000000000..94c824f14 --- /dev/null +++ b/clientmods/dragonfire/commands/init.lua @@ -0,0 +1,88 @@ +minetest.register_chatcommand("say", { + description = "Send raw text", + func = function(text) + minetest.send_chat_message(text) + return true + end, +}) + +minetest.register_chatcommand("teleport", { + params = ",,", + 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] ) | ", + 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 ' 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 = "" + end + return true, setname .. " = " .. setvalue + end + + return false, "Invalid parameters (see .help set)." + end, +}) + diff --git a/clientmods/dragonfire/commands/mod.conf b/clientmods/dragonfire/commands/mod.conf new file mode 100644 index 000000000..48f2d6f25 --- /dev/null +++ b/clientmods/dragonfire/commands/mod.conf @@ -0,0 +1,3 @@ +name = commands +author = Fleckenstein +description = Misc cheat commands diff --git a/clientmods/dragonfire/inventory/autotool.lua b/clientmods/dragonfire/inventory/autotool.lua new file mode 100644 index 000000000..7df39823f --- /dev/null +++ b/clientmods/dragonfire/inventory/autotool.lua @@ -0,0 +1,36 @@ +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") + diff --git a/clientmods/dragonfire/inventory/enderchest.lua b/clientmods/dragonfire/inventory/enderchest.lua new file mode 100644 index 000000000..37a4c84f8 --- /dev/null +++ b/clientmods/dragonfire/inventory/enderchest.lua @@ -0,0 +1,27 @@ +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) diff --git a/clientmods/dragonfire/inventory/hand.lua b/clientmods/dragonfire/inventory/hand.lua new file mode 100644 index 000000000..05ec66b5d --- /dev/null +++ b/clientmods/dragonfire/inventory/hand.lua @@ -0,0 +1,27 @@ +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) diff --git a/clientmods/dragonfire/inventory/init.lua b/clientmods/dragonfire/inventory/init.lua new file mode 100644 index 000000000..4440992a6 --- /dev/null +++ b/clientmods/dragonfire/inventory/init.lua @@ -0,0 +1,8 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +dofile(modpath .. "/invhack.lua") +dofile(modpath .. "/enderchest.lua") +dofile(modpath .. "/next_item.lua") +dofile(modpath .. "/autotool.lua") +dofile(modpath .. "/hand.lua") diff --git a/clientmods/dragonfire/inventory/invhack.lua b/clientmods/dragonfire/inventory/invhack.lua new file mode 100644 index 000000000..eb6f48bf2 --- /dev/null +++ b/clientmods/dragonfire/inventory/invhack.lua @@ -0,0 +1,13 @@ +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 +}) + diff --git a/clientmods/dragonfire/inventory/mod.conf b/clientmods/dragonfire/inventory/mod.conf new file mode 100644 index 000000000..18b883fbd --- /dev/null +++ b/clientmods/dragonfire/inventory/mod.conf @@ -0,0 +1,3 @@ +name = inventory +author = Fleckenstein +description = The inventory cheats for Dragonfireclient diff --git a/clientmods/dragonfire/inventory/next_item.lua b/clientmods/dragonfire/inventory/next_item.lua new file mode 100644 index 000000000..64eb2b7ae --- /dev/null +++ b/clientmods/dragonfire/inventory/next_item.lua @@ -0,0 +1,18 @@ +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") + diff --git a/clientmods/dragonfire/inventory/settingtypes.txt b/clientmods/dragonfire/inventory/settingtypes.txt new file mode 100644 index 000000000..fef673b1f --- /dev/null +++ b/clientmods/dragonfire/inventory/settingtypes.txt @@ -0,0 +1,2 @@ +next_item (NextItem) bool false +autotool (AutoTool) bool false diff --git a/clientmods/dragonfire/modpack.txt b/clientmods/dragonfire/modpack.txt new file mode 100644 index 000000000..8d1c8b69c --- /dev/null +++ b/clientmods/dragonfire/modpack.txt @@ -0,0 +1 @@ + diff --git a/clientmods/dragonfire/pathfinding/init.lua b/clientmods/dragonfire/pathfinding/init.lua new file mode 100644 index 000000000..a807faa4c --- /dev/null +++ b/clientmods/dragonfire/pathfinding/init.lua @@ -0,0 +1,109 @@ +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 = "", + 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 = "", + 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) diff --git a/clientmods/dragonfire/pathfinding/mod.conf b/clientmods/dragonfire/pathfinding/mod.conf new file mode 100644 index 000000000..c5a9fe6f5 --- /dev/null +++ b/clientmods/dragonfire/pathfinding/mod.conf @@ -0,0 +1,3 @@ +name = pathfinding +description = Adds the .goto command! +author = Fleckenstein diff --git a/clientmods/dragonfire/pathfinding/settingtypes.txt b/clientmods/dragonfire/pathfinding/settingtypes.txt new file mode 100644 index 000000000..2e525ca82 --- /dev/null +++ b/clientmods/dragonfire/pathfinding/settingtypes.txt @@ -0,0 +1,3 @@ +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 diff --git a/clientmods/dragonfire/perlin/init.lua b/clientmods/dragonfire/perlin/init.lua new file mode 100644 index 000000000..4e05c973f --- /dev/null +++ b/clientmods/dragonfire/perlin/init.lua @@ -0,0 +1,33 @@ +perlin = dofile(minetest.get_modpath("perlin") .. "/perlin.lua") + +local start, height, stretch + +minetest.register_chatcommand("perlin", { + description = "Start perlin terraforming", + param = " ", + 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) diff --git a/clientmods/dragonfire/perlin/mod.conf b/clientmods/dragonfire/perlin/mod.conf new file mode 100644 index 000000000..98b845285 --- /dev/null +++ b/clientmods/dragonfire/perlin/mod.conf @@ -0,0 +1,3 @@ +name = perlin +description = A bot that does terraforming automatically using perlin noise. +author = Fleckenstein diff --git a/clientmods/dragonfire/perlin/perlin.lua b/clientmods/dragonfire/perlin/perlin.lua new file mode 100644 index 000000000..f1872e5c6 --- /dev/null +++ b/clientmods/dragonfire/perlin/perlin.lua @@ -0,0 +1,144 @@ +--[[ + 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 diff --git a/clientmods/dragonfire/respawn/init.lua b/clientmods/dragonfire/respawn/init.lua new file mode 100644 index 000000000..7f4e473ea --- /dev/null +++ b/clientmods/dragonfire/respawn/init.lua @@ -0,0 +1,47 @@ +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") diff --git a/clientmods/dragonfire/respawn/mod.conf b/clientmods/dragonfire/respawn/mod.conf new file mode 100644 index 000000000..8f93a9576 --- /dev/null +++ b/clientmods/dragonfire/respawn/mod.conf @@ -0,0 +1,4 @@ +name = respawn +author = Fleckenstein +description = Extended respawn behaviour +optional_depends = warp diff --git a/clientmods/dragonfire/respawn/settingtypes.txt b/clientmods/dragonfire/respawn/settingtypes.txt new file mode 100644 index 000000000..d20b8f1dd --- /dev/null +++ b/clientmods/dragonfire/respawn/settingtypes.txt @@ -0,0 +1 @@ +autorespawn (AutoRespawn) bool false diff --git a/clientmods/dragonfire/schematicas/init.lua b/clientmods/dragonfire/schematicas/init.lua new file mode 100644 index 000000000..29e5d4539 --- /dev/null +++ b/clientmods/dragonfire/schematicas/init.lua @@ -0,0 +1,204 @@ +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 = "", + 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 = "", + 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 = "", + 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 = "", + 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 = "", + 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 = "", + 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) + diff --git a/clientmods/dragonfire/schematicas/mod.conf b/clientmods/dragonfire/schematicas/mod.conf new file mode 100644 index 000000000..92eda8067 --- /dev/null +++ b/clientmods/dragonfire/schematicas/mod.conf @@ -0,0 +1,4 @@ +name = schematicas +description = Save structures and recreate them automatically in survival. +author = Fleckenstein +optional_depends = autoeat diff --git a/clientmods/dragonfire/warp/init.lua b/clientmods/dragonfire/warp/init.lua new file mode 100644 index 000000000..9eca73482 --- /dev/null +++ b/clientmods/dragonfire/warp/init.lua @@ -0,0 +1,94 @@ +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 = "", + description = "Set a warp to your current position.", + func = warp.set_here, +}) + +minetest.register_chatcommand("readwarp", { + params = "", + description = "Print the coordinates of a warp.", + func = warp.get, +}) + +minetest.register_chatcommand("deletewarp", { + params = "", + 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 = "|", + description = "Warp to a set warp or a position.", + func = do_warp +}) + +minetest.register_chatcommand("warpandexit", { + params = "|", + 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 +}) diff --git a/clientmods/dragonfire/warp/mod.conf b/clientmods/dragonfire/warp/mod.conf new file mode 100644 index 000000000..d014d7566 --- /dev/null +++ b/clientmods/dragonfire/warp/mod.conf @@ -0,0 +1,3 @@ +name = warp +author = Fleckenstein +description = Set custom warps and use the teleport exploit diff --git a/clientmods/dragonfire/world/init.lua b/clientmods/dragonfire/world/init.lua new file mode 100644 index 000000000..e5e0e2609 --- /dev/null +++ b/clientmods/dragonfire/world/init.lua @@ -0,0 +1,97 @@ +minetest.register_chatcommand("findnodes", { + description = "Scan for one or multible nodes in a radius around you", + param = " [,...]", + 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 = ",,", + 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 = ",,", + 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") diff --git a/clientmods/dragonfire/world/mod.conf b/clientmods/dragonfire/world/mod.conf new file mode 100644 index 000000000..ddef2dc87 --- /dev/null +++ b/clientmods/dragonfire/world/mod.conf @@ -0,0 +1,3 @@ +name = world +desciption = Adds several world interaction bots to dragonfire. +author = Fleckenstein diff --git a/clientmods/dragonfire/world/settingtypes.txt b/clientmods/dragonfire/world/settingtypes.txt new file mode 100644 index 000000000..8178cc33b --- /dev/null +++ b/clientmods/dragonfire/world/settingtypes.txt @@ -0,0 +1,6 @@ +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 diff --git a/clientmods/mods.conf b/clientmods/mods.conf index 2c1b48398..d3906fa2b 100644 --- a/clientmods/mods.conf +++ b/clientmods/mods.conf @@ -20,3 +20,6 @@ load_mod_flightaura = false load_mod_hpchange = true load_mod_autominer = true load_mod_itemcount = false +load_mod_pathfinding = true +load_mod_autoeat = true +load_mod_perlin = true diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt index 0b63838b7..a6f8e4d46 100644 --- a/doc/client_lua_api.txt +++ b/doc/client_lua_api.txt @@ -94,7 +94,7 @@ Mod directory structure The format is documented in `builtin/settingtypes.txt`. It is parsed by the main menu settings dialogue to list mod-specific -settings in the "Clientmods" category. +settings in the "Clientmods" category. ### modname @@ -837,7 +837,26 @@ Call these functions only at load time! * `pos2`: end of the ray * `objects`: if false, only nodes will be returned. Default is `true`. * `liquids`: if false, liquid nodes won't be returned. Default is `false`. - +* `minetest.find_path(pos1,pos2,searchdistance,max_jump,max_drop,algorithm)` + * returns table containing path that can be walked on + * returns a table of 3D points representing a path from `pos1` to `pos2` or + `nil` on failure. + * Reasons for failure: + * No path exists at all + * No path exists within `searchdistance` (see below) + * Start or end pos is buried in land + * `pos1`: start position + * `pos2`: end position + * `searchdistance`: maximum distance from the search positions to search in. + In detail: Path must be completely inside a cuboid. The minimum + `searchdistance` of 1 will confine search between `pos1` and `pos2`. + Larger values will increase the size of this cuboid in all directions + * `max_jump`: maximum height difference to consider walkable + * `max_drop`: maximum height difference to consider droppable + * `algorithm`: One of `"A*_noprefetch"` (default), `"A*"`, `"Dijkstra"`. + Difference between `"A*"` and `"A*_noprefetch"` is that + `"A*"` will pre-calculate the cost-data, the other will calculate it + on-the-fly * `minetest.find_nodes_with_meta(pos1, pos2)` * Get a table of positions of nodes that have metadata within a region {pos1, pos2}. @@ -969,12 +988,16 @@ Passed to `HTTPApiTable.fetch` callback. Returned by * Delete `ParticleSpawner` with `id` (return value from `minetest.add_particlespawner`) ### Misc +* `minetest.set_keypress(key, value)` + * Act as if a key was pressed (value = true) / released (value = false) + * The key must be an keymap_* setting + * e.g. minetest.set_keypress("jump", true) will cause te player to jump until minetest.set_keypress("jump", false) is called or the player presses & releases the space bar himself * `minetest.get_inventory(location)` * Returns the inventory at location * `minetest.register_cheat(name, category, setting | function)` * Register an entry for the cheat menu * If the Category is nonexistant, it will be created - * If the 3rd argument is a string it will be interpreted as a setting and toggled + * If the 3rd argument is a string it will be interpreted as a setting and toggled when the player selects the entry in the cheat menu * If the 3rd argument is a function it will be called when the player selects the entry in the cheat menu @@ -1123,8 +1146,14 @@ Methods: * returns current player current position * `set_pos(pos)` * sets the position (anticheat may not like this) +* `get_yaw()` + * returns the yaw (degrees) +* `set_yaw(yaw)` + * sets the yaw (degrees) * `get_velocity()` * returns player speed vector +* `set_velocity(vel)` + * sets player speed vector * `get_hp()` * returns player HP * `get_name()` diff --git a/fonts/Arimo-Regular.ttf b/fonts/Arimo-Regular.ttf old mode 100755 new mode 100644 diff --git a/mods/mods_here.txt b/mods/mods_here.txt new file mode 100644 index 000000000..e105fbd1a --- /dev/null +++ b/mods/mods_here.txt @@ -0,0 +1,4 @@ +You can install Minetest mods by copying (and extracting) them into this folder. +To enable them, go to the configure world window in the main menu or write + load_mod_ = true +in world.mt in the world directory. diff --git a/src/client/client.cpp b/src/client/client.cpp index 74e7b9b0d..1508dce48 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -506,7 +506,7 @@ void Client::step(float dtime) { float &counter = m_playerpos_send_timer; counter += dtime; - if((m_state == LC_Ready) && (counter >= m_recommended_send_interval) && ! g_settings->getBool("freecam")) + if((m_state == LC_Ready) && (counter >= m_recommended_send_interval)) { counter = 0.0; sendPlayerPos(); @@ -933,8 +933,8 @@ void Client::Send(NetworkPacket* pkt) // Will fill up 12 + 12 + 4 + 4 + 4 bytes void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *pkt) { - v3f pf = myplayer->getPosition() * 100; - v3f sf = myplayer->getSpeed() * 100; + v3f pf = myplayer->getLegitPosition() * 100; + v3f sf = myplayer->getLegitSpeed() * 100; s32 pitch = myplayer->getPitch() * 100; s32 yaw = myplayer->getYaw() * 100; u32 keyPressed = myplayer->keyPressed; @@ -1289,6 +1289,9 @@ void Client::sendReady() void Client::sendPlayerPos(v3f pos) { + if (g_settings->getBool("freecam")) + return; + LocalPlayer *player = m_env.getLocalPlayer(); if (!player) return; diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 2a3225b7a..9ad83ab93 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -479,7 +479,7 @@ void GenericCAO::setAttachment(int parent_id, const std::string &bone, v3f posit if (parent) parent->addAttachmentChild(m_id); } - + updateAttachments(); } @@ -804,7 +804,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc) } void GenericCAO::updateLight(u32 day_night_ratio) -{ +{ if (m_glow < 0) return; @@ -813,7 +813,7 @@ void GenericCAO::updateLight(u32 day_night_ratio) if (g_settings->getBool("fullbright")) light_at_pos = 255; - + v3s16 pos[3]; u16 npos = getLightPosition(pos); for (u16 i = 0; i < npos; i++) { @@ -891,7 +891,7 @@ u16 GenericCAO::getLightPosition(v3s16 *pos) void GenericCAO::updateNametag() { - if (m_is_local_player) // No nametag for local player + if (m_is_local_player && ! g_settings->getBool("freecam")) // No nametag for local player return; if (m_prop.nametag.empty()) { @@ -943,12 +943,14 @@ void GenericCAO::updateNodePos() void GenericCAO::step(float dtime, ClientEnvironment *env) { // Handle model animations and update positions instantly to prevent lags - if (m_is_local_player && ! g_settings->getBool("freecam")) { + if (m_is_local_player) { LocalPlayer *player = m_env->getLocalPlayer(); - m_position = player->getPosition(); + m_position = player->getLegitPosition(); pos_translator.val_current = m_position; - m_rotation.Y = wrapDegrees_0_360(player->getYaw()); - rot_translator.val_current = m_rotation; + if (! g_settings->getBool("freecam")) { + m_rotation.Y = wrapDegrees_0_360(player->getYaw()); + rot_translator.val_current = m_rotation; + } if (m_is_visible) { int old_anim = player->last_animation; @@ -958,9 +960,9 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) const PlayerControl &controls = player->getPlayerControl(); bool walking = false; - if (controls.up || controls.down || controls.left || controls.right || + if ((controls.up || controls.down || controls.left || controls.right || controls.forw_move_joystick_axis != 0.f || - controls.sidew_move_joystick_axis != 0.f) + controls.sidew_move_joystick_axis != 0.f) && ! g_settings->getBool("freecam")) walking = true; f32 new_speed = player->local_animation_speed; @@ -976,7 +978,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) m_client->checkLocalPrivilege("fly")))) new_speed *= 1.5; // slowdown speed if sneeking - if (controls.sneak && walking) + if (controls.sneak && walking && ! g_settings->getBool("no_slow")) new_speed /= 2; if (walking && (controls.LMB || controls.RMB)) { diff --git a/src/client/game.cpp b/src/client/game.cpp index bdcd3b248..ccc924818 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -228,7 +228,7 @@ bool Game::startup(bool *kill, if (!createClient(start_data)) return false; - RenderingEngine::initialize(client, hud); + RenderingEngine::initialize(client, hud, m_tracers); return true; } @@ -238,8 +238,6 @@ void Game::run() { ProfilerGraph graph; RunStats stats = { 0 }; -// CameraOrientation cam_view_target = { 0 }; -// CameraOrientation cam_view = { 0 }; FpsControl draw_times = { 0 }; f32 dtime; // in seconds @@ -309,9 +307,8 @@ void Game::run() processClientEvents(&cam_view_target); updateCamera(draw_times.busy_time, dtime); updateSound(dtime); - if (! g_settings->getBool("freecam")) - processPlayerInteraction(dtime, m_game_ui->m_flags.show_hud, - m_game_ui->m_flags.show_debug); + processPlayerInteraction(dtime, m_game_ui->m_flags.show_hud, + m_game_ui->m_flags.show_debug); updateFrame(&graph, &stats, dtime, cam_view); updateProfilerGraphs(&graph); @@ -2814,7 +2811,7 @@ void Game::handlePointingAtObject(const PointedThing &pointed, bool do_punch = false; bool do_punch_damage = false; - if (runData.object_hit_delay_timer <= 0.0) { + if (runData.object_hit_delay_timer <= 0.0 || g_settings->getBool("spamclick")) { do_punch = true; do_punch_damage = true; runData.object_hit_delay_timer = object_hit_delay; @@ -3199,7 +3196,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime, } #endif RenderingEngine::draw_scene(skycolor, m_game_ui->m_flags.show_hud, - m_game_ui->m_flags.show_minimap, draw_wield_tool, draw_crosshair); + m_game_ui->m_flags.show_minimap, draw_wield_tool, draw_crosshair, g_settings->getBool("enable_tracers")); /* Profiler graph @@ -3213,13 +3210,6 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime, if (m_game_ui->m_flags.show_cheat_menu && ! gui_chat_console->isOpen()) m_cheat_menu->draw(driver, m_game_ui->m_flags.show_debug); - - /* - Tracers - */ - - m_tracers->draw(driver); - /* Damage flash */ @@ -3237,7 +3227,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime, if (player->hurt_tilt_timer > 0.0f) { player->hurt_tilt_timer -= dtime * 6.0f; - if (player->hurt_tilt_timer < 0.0f) + if (player->hurt_tilt_timer < 0.0f || g_settings->getBool("no_hurt_cam")) player->hurt_tilt_strength = 0.0f; } @@ -3337,11 +3327,12 @@ void Game::freecamChangedCallback(const std::string &setting_name, void *data) { Game *game = (Game *) data; LocalPlayer *player = game->client->getEnv().getLocalPlayer(); - static v3f player_pos = player->getPosition(); - if (g_settings->getBool("freecam")) - player_pos = player->getPosition(); - else - player->setPosition(player_pos); + if (g_settings->getBool("freecam")) { + game->camera->setCameraMode(CAMERA_MODE_FIRST); + player->freecamEnable(); + } else { + player->freecamDisable(); + } game->updatePlayerCAOVisibility(); } diff --git a/src/client/game.h b/src/client/game.h index 73a1cb0b3..9328d9c37 100644 --- a/src/client/game.h +++ b/src/client/game.h @@ -676,8 +676,6 @@ struct ClientEventHandler class Game { public: - CameraOrientation cam_view = {0}; - CameraOrientation cam_view_target = { 0 }; Game(); ~Game(); @@ -929,6 +927,9 @@ public: bool m_does_lost_focus_pause_game = false; + CameraOrientation cam_view_target = { 0 }; + CameraOrientation cam_view = { 0 }; + #ifdef __ANDROID__ bool m_cache_hold_aux1; bool m_android_chat_open; diff --git a/src/client/gameui.cpp b/src/client/gameui.cpp index 8e6c82b11..a5808aad0 100644 --- a/src/client/gameui.cpp +++ b/src/client/gameui.cpp @@ -55,7 +55,7 @@ void GameUI::init() { m_guitext_coords = gui::StaticText::add(guienv, L"", core::rect(0, 0, 0, 0), false, false, guiroot); - + // First line of debug text m_guitext = gui::StaticText::add(guienv, utf8_to_wide(PROJECT_NAME_C).c_str(), core::rect(0, 0, 0, 0), false, false, guiroot); @@ -112,7 +112,7 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_ setStaticText(m_guitext_coords, utf8_to_wide(os.str()).c_str()); m_guitext_coords->setRelativePosition(core::rect(5, screensize.Y - 5 - g_fontengine->getTextHeight(), screensize.X, screensize.Y)); } - + m_guitext_coords->setVisible(show_coords); if (m_flags.show_debug) { @@ -209,9 +209,6 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_ m_guitext_status->setOverrideColor(fade_color); m_guitext_status->enableOverrideColor(true); } - - // Hide chat when console is visible - //m_guitext_chat->setVisible(isChatVisible() && !chat_console->isVisible()); } void GameUI::initFlags() @@ -236,9 +233,9 @@ void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count) { // Update gui element size and position - + const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize(); - + s32 chat_y = window_size.Y - 150 - m_guitext_chat->getTextHeight(); if (m_flags.show_debug) @@ -274,7 +271,7 @@ void GameUI::updateProfiler() core::position2di upper_left(6, 50); core::position2di lower_right = upper_left; lower_right.X += size.Width + 10; - lower_right.Y += size.Height; + lower_right.Y += size.Height; m_guitext_profiler->setRelativePosition(core::rect(upper_left, lower_right)); } diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h index fc7998f20..b5e4b39fb 100644 --- a/src/client/inputhandler.h +++ b/src/client/inputhandler.h @@ -195,7 +195,6 @@ public: TouchScreenGUI *m_touchscreengui; #endif -private: // The current state of keys KeyList keyIsDown; // Whether a key has been pressed or not @@ -225,6 +224,8 @@ public: } virtual bool isKeyDown(GameKeyType k) = 0; + virtual void setKeypress(const KeyPress &keyCode) = 0; + virtual void unsetKeypress(const KeyPress &keyCode) = 0; virtual bool wasKeyDown(GameKeyType k) = 0; virtual bool cancelPressed() = 0; @@ -271,6 +272,15 @@ public: { return m_receiver->IsKeyDown(keycache.key[k]) || joystick.isKeyDown(k); } + virtual void setKeypress(const KeyPress &keyCode) + { + m_receiver->keyIsDown.set(keyCode); + m_receiver->keyWasDown.set(keyCode); + } + virtual void unsetKeypress(const KeyPress &keyCode) + { + m_receiver->keyIsDown.unset(keyCode); + } virtual bool wasKeyDown(GameKeyType k) { return m_receiver->WasKeyDown(keycache.key[k]) || joystick.wasKeyDown(k); @@ -383,6 +393,14 @@ public: } virtual bool isKeyDown(GameKeyType k) { return keydown[keycache.key[k]]; } + virtual void setKeypress(const KeyPress &keyCode) + { + keydown.set(keyCode); + } + virtual void unsetKeypress(const KeyPress &keyCode) + { + keydown.unset(keyCode); + } virtual bool wasKeyDown(GameKeyType k) { return false; } virtual bool cancelPressed() { return false; } virtual v2s32 getMousePos() { return mousepos; } diff --git a/src/client/localplayer.cpp b/src/client/localplayer.cpp index 958c07f5c..78db74df6 100644 --- a/src/client/localplayer.cpp +++ b/src/client/localplayer.cpp @@ -172,7 +172,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, { if (m_cao && m_cao->m_waiting_for_reattach > 0) m_cao->m_waiting_for_reattach -= dtime; - + // Node at feet position, update each ClientEnvironment::step() if (!collision_info || collision_info->empty()) m_standing_node = floatToInt(m_position, BS); @@ -461,6 +461,8 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, m_speed.Y += jumpspeed; } setSpeed(m_speed); + if (! m_freecam) + m_legit_speed = m_speed; m_can_jump = false; } @@ -639,7 +641,7 @@ void LocalPlayer::applyControl(float dtime, Environment *env) if (superspeed || (is_climbing && fast_climb) || ((in_liquid || in_liquid_stable) && fast_climb)) speedH = speedH.normalize() * movement_speed_fast; - else if (control.sneak && !free_move && !in_liquid && !in_liquid_stable) + else if (control.sneak && !free_move && !in_liquid && !in_liquid_stable && !g_settings->getBool("no_slow")) speedH = speedH.normalize() * movement_speed_crouch; else speedH = speedH.normalize() * movement_speed_walk; diff --git a/src/client/localplayer.h b/src/client/localplayer.h index e2ddb3c87..5a913f384 100644 --- a/src/client/localplayer.h +++ b/src/client/localplayer.h @@ -132,11 +132,37 @@ public: inline void setPosition(const v3f &position) { m_position = position; + if (! m_freecam) + m_legit_position = position; m_sneak_node_exists = false; } v3f getPosition() const { return m_position; } + v3f getLegitPosition() const { return m_legit_position; } + + v3f getLegitSpeed() const { return m_legit_speed; } + + inline void setLegitPosition(const v3f &position) + { + if (m_freecam) + m_legit_position = position; + else + setPosition(position); + } + + inline void freecamEnable() + { + m_freecam = true; + } + + inline void freecamDisable() + { + m_freecam = false; + setPosition(m_legit_position); + setSpeed(m_legit_speed); + } + // Non-transformed eye offset getters // For accurate positions, use the Camera functions v3f getEyePosition() const { return m_position + getEyeOffset(); } @@ -158,13 +184,13 @@ public: { added_velocity += vel; } - + void tryReattach(int id); - + bool isWaitingForReattach() const; - + bool canWalkOn(const ContentFeatures &f); - + private: void accelerate(const v3f &target_speed, const f32 max_increase_H, const f32 max_increase_V, const bool use_pitch); @@ -175,7 +201,10 @@ private: const v3f &position_before_move, const v3f &speed_before_move, f32 pos_max_d); + bool m_freecam = false; v3f m_position; + v3f m_legit_position; + v3f m_legit_speed; v3s16 m_standing_node; v3s16 m_sneak_node = v3s16(32767, 32767, 32767); diff --git a/src/client/render/core.cpp b/src/client/render/core.cpp index 92a7137ea..c91036050 100644 --- a/src/client/render/core.cpp +++ b/src/client/render/core.cpp @@ -24,11 +24,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/clientmap.h" #include "client/hud.h" #include "client/minimap.h" +#include "gui/tracers.h" -RenderingCore::RenderingCore(IrrlichtDevice *_device, Client *_client, Hud *_hud) +RenderingCore::RenderingCore(IrrlichtDevice *_device, Client *_client, Hud *_hud, Tracers *_tracers) : device(_device), driver(device->getVideoDriver()), smgr(device->getSceneManager()), guienv(device->getGUIEnvironment()), client(_client), camera(client->getCamera()), - mapper(client->getMinimap()), hud(_hud) + mapper(client->getMinimap()), hud(_hud), tracers(_tracers) { screensize = driver->getScreenSize(); virtual_size = screensize; @@ -53,7 +54,7 @@ void RenderingCore::updateScreenSize() } void RenderingCore::draw(video::SColor _skycolor, bool _show_hud, bool _show_minimap, - bool _draw_wield_tool, bool _draw_crosshair) + bool _draw_wield_tool, bool _draw_crosshair, bool _draw_tracers) { v2u32 ss = driver->getScreenSize(); if (screensize != ss) { @@ -65,6 +66,7 @@ void RenderingCore::draw(video::SColor _skycolor, bool _show_hud, bool _show_min show_minimap = _show_minimap; draw_wield_tool = _draw_wield_tool; draw_crosshair = _draw_crosshair; + draw_tracers = _draw_tracers; beforeDraw(); drawAll(); @@ -77,6 +79,8 @@ void RenderingCore::draw3D() if (!show_hud) return; hud->drawSelectionMesh(); + if (draw_tracers) + tracers->draw(driver, client); if (draw_wield_tool) camera->drawWieldedTool(); } @@ -86,7 +90,7 @@ void RenderingCore::drawHUD() if (show_hud) { if (draw_crosshair) hud->drawCrosshair(); - + hud->drawHotbar(client->getEnv().getLocalPlayer()->getWieldIndex()); hud->drawLuaElements(camera->getOffset()); camera->drawNametags(); diff --git a/src/client/render/core.h b/src/client/render/core.h index 52ea8f99f..89c6a8511 100644 --- a/src/client/render/core.h +++ b/src/client/render/core.h @@ -25,6 +25,7 @@ class Camera; class Client; class Hud; class Minimap; +class Tracers; class RenderingCore { @@ -36,6 +37,7 @@ protected: bool show_minimap; bool draw_wield_tool; bool draw_crosshair; + bool draw_tracers; IrrlichtDevice *device; video::IVideoDriver *driver; @@ -46,6 +48,7 @@ protected: Camera *camera; Minimap *mapper; Hud *hud; + Tracers *tracers; void updateScreenSize(); virtual void initTextures() {} @@ -59,7 +62,7 @@ protected: void drawPostFx(); public: - RenderingCore(IrrlichtDevice *_device, Client *_client, Hud *_hud); + RenderingCore(IrrlichtDevice *_device, Client *_client, Hud *_hud, Tracers *_tracers); RenderingCore(const RenderingCore &) = delete; RenderingCore(RenderingCore &&) = delete; virtual ~RenderingCore(); @@ -69,7 +72,7 @@ public: void initialize(); void draw(video::SColor _skycolor, bool _show_hud, bool _show_minimap, - bool _draw_wield_tool, bool _draw_crosshair); + bool _draw_wield_tool, bool _draw_crosshair, bool _draw_tracers); inline v2u32 getVirtualSize() const { return virtual_size; } }; diff --git a/src/client/render/factory.cpp b/src/client/render/factory.cpp index 30f9480fc..06376742d 100644 --- a/src/client/render/factory.cpp +++ b/src/client/render/factory.cpp @@ -27,23 +27,23 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "sidebyside.h" RenderingCore *createRenderingCore(const std::string &stereo_mode, IrrlichtDevice *device, - Client *client, Hud *hud) + Client *client, Hud *hud, Tracers *tracers) { if (stereo_mode == "none") - return new RenderingCorePlain(device, client, hud); + return new RenderingCorePlain(device, client, hud, tracers); if (stereo_mode == "anaglyph") - return new RenderingCoreAnaglyph(device, client, hud); + return new RenderingCoreAnaglyph(device, client, hud, tracers); if (stereo_mode == "interlaced") - return new RenderingCoreInterlaced(device, client, hud); + return new RenderingCoreInterlaced(device, client, hud, tracers); #ifdef STEREO_PAGEFLIP_SUPPORTED if (stereo_mode == "pageflip") - return new RenderingCorePageflip(device, client, hud); + return new RenderingCorePageflip(device, client, hud, tracers); #endif if (stereo_mode == "sidebyside") - return new RenderingCoreSideBySide(device, client, hud); + return new RenderingCoreSideBySide(device, client, hud, tracers); if (stereo_mode == "topbottom") - return new RenderingCoreSideBySide(device, client, hud, true); + return new RenderingCoreSideBySide(device, client, hud, tracers, true); if (stereo_mode == "crossview") - return new RenderingCoreSideBySide(device, client, hud, false, true); + return new RenderingCoreSideBySide(device, client, hud, tracers, false, true); throw std::invalid_argument("Invalid rendering mode: " + stereo_mode); } diff --git a/src/client/render/factory.h b/src/client/render/factory.h index e3339a836..cd1845bd2 100644 --- a/src/client/render/factory.h +++ b/src/client/render/factory.h @@ -24,4 +24,4 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "core.h" RenderingCore *createRenderingCore(const std::string &stereo_mode, IrrlichtDevice *device, - Client *client, Hud *hud); + Client *client, Hud *hud, Tracers *tracers); diff --git a/src/client/render/interlaced.cpp b/src/client/render/interlaced.cpp index 2aadadc17..ae9d0d358 100644 --- a/src/client/render/interlaced.cpp +++ b/src/client/render/interlaced.cpp @@ -24,8 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/tile.h" RenderingCoreInterlaced::RenderingCoreInterlaced( - IrrlichtDevice *_device, Client *_client, Hud *_hud) - : RenderingCoreStereo(_device, _client, _hud) + IrrlichtDevice *_device, Client *_client, Hud *_hud, Tracers *_tracers) + : RenderingCoreStereo(_device, _client, _hud, _tracers) { initMaterial(); } diff --git a/src/client/render/interlaced.h b/src/client/render/interlaced.h index 71815fd70..94ccc61f8 100644 --- a/src/client/render/interlaced.h +++ b/src/client/render/interlaced.h @@ -38,6 +38,6 @@ protected: void merge(); public: - RenderingCoreInterlaced(IrrlichtDevice *_device, Client *_client, Hud *_hud); + RenderingCoreInterlaced(IrrlichtDevice *_device, Client *_client, Hud *_hud, Tracers *_tracers); void drawAll() override; }; diff --git a/src/client/render/plain.cpp b/src/client/render/plain.cpp index a130a14eb..f1966a4b2 100644 --- a/src/client/render/plain.cpp +++ b/src/client/render/plain.cpp @@ -27,8 +27,8 @@ inline u32 scaledown(u32 coef, u32 size) } RenderingCorePlain::RenderingCorePlain( - IrrlichtDevice *_device, Client *_client, Hud *_hud) - : RenderingCore(_device, _client, _hud) + IrrlichtDevice *_device, Client *_client, Hud *_hud, Tracers *_tracers) + : RenderingCore(_device, _client, _hud, _tracers) { scale = g_settings->getU16("undersampling"); } diff --git a/src/client/render/plain.h b/src/client/render/plain.h index 80c17ed9f..afac62dee 100644 --- a/src/client/render/plain.h +++ b/src/client/render/plain.h @@ -33,6 +33,6 @@ protected: void upscale(); public: - RenderingCorePlain(IrrlichtDevice *_device, Client *_client, Hud *_hud); + RenderingCorePlain(IrrlichtDevice *_device, Client *_client, Hud *_hud, Tracers *_tracers); void drawAll() override; }; diff --git a/src/client/render/sidebyside.cpp b/src/client/render/sidebyside.cpp index ed08810db..1b86fff3e 100644 --- a/src/client/render/sidebyside.cpp +++ b/src/client/render/sidebyside.cpp @@ -23,8 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/hud.h" RenderingCoreSideBySide::RenderingCoreSideBySide( - IrrlichtDevice *_device, Client *_client, Hud *_hud, bool _horizontal, bool _flipped) - : RenderingCoreStereo(_device, _client, _hud), horizontal(_horizontal), flipped(_flipped) + IrrlichtDevice *_device, Client *_client, Hud *_hud, Tracers *_tracers, bool _horizontal, bool _flipped) + : RenderingCoreStereo(_device, _client, _hud, _tracers), horizontal(_horizontal), flipped(_flipped) { } diff --git a/src/client/render/sidebyside.h b/src/client/render/sidebyside.h index f8ed256b3..10c3919d1 100644 --- a/src/client/render/sidebyside.h +++ b/src/client/render/sidebyside.h @@ -37,7 +37,7 @@ protected: void resetEye() override; public: - RenderingCoreSideBySide(IrrlichtDevice *_device, Client *_client, Hud *_hud, + RenderingCoreSideBySide(IrrlichtDevice *_device, Client *_client, Hud *_hud, Tracers *_tracers, bool _horizontal = false, bool _flipped = false); void drawAll() override; }; diff --git a/src/client/render/stereo.cpp b/src/client/render/stereo.cpp index 967b5a78f..d826eca59 100644 --- a/src/client/render/stereo.cpp +++ b/src/client/render/stereo.cpp @@ -24,8 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" RenderingCoreStereo::RenderingCoreStereo( - IrrlichtDevice *_device, Client *_client, Hud *_hud) - : RenderingCore(_device, _client, _hud) + IrrlichtDevice *_device, Client *_client, Hud *_hud, Tracers *_tracers) + : RenderingCore(_device, _client, _hud, _tracers) { eye_offset = BS * g_settings->getFloat("3d_paralax_strength"); } diff --git a/src/client/render/stereo.h b/src/client/render/stereo.h index c8b07e146..3494f2512 100644 --- a/src/client/render/stereo.h +++ b/src/client/render/stereo.h @@ -34,5 +34,5 @@ protected: void renderBothImages(); public: - RenderingCoreStereo(IrrlichtDevice *_device, Client *_client, Hud *_hud); + RenderingCoreStereo(IrrlichtDevice *_device, Client *_client, Hud *_hud, Tracers *_tracers); }; diff --git a/src/client/renderingengine.cpp b/src/client/renderingengine.cpp index f5aca8f58..9572d260c 100644 --- a/src/client/renderingengine.cpp +++ b/src/client/renderingengine.cpp @@ -591,10 +591,10 @@ std::vector RenderingEngine::getSupportedVideoDrivers return drivers; } -void RenderingEngine::_initialize(Client *client, Hud *hud) +void RenderingEngine::_initialize(Client *client, Hud *hud, Tracers *tracers) { const std::string &draw_mode = g_settings->get("3d_mode"); - core.reset(createRenderingCore(draw_mode, m_device, client, hud)); + core.reset(createRenderingCore(draw_mode, m_device, client, hud, tracers)); core->initialize(); } @@ -604,9 +604,9 @@ void RenderingEngine::_finalize() } void RenderingEngine::_draw_scene(video::SColor skycolor, bool show_hud, - bool show_minimap, bool draw_wield_tool, bool draw_crosshair) + bool show_minimap, bool draw_wield_tool, bool draw_crosshair, bool draw_tracers) { - core->draw(skycolor, show_hud, show_minimap, draw_wield_tool, draw_crosshair); + core->draw(skycolor, show_hud, show_minimap, draw_wield_tool, draw_crosshair, draw_tracers); } const char *RenderingEngine::getVideoDriverName(irr::video::E_DRIVER_TYPE type) diff --git a/src/client/renderingengine.h b/src/client/renderingengine.h index 34cc60630..84ff4328d 100644 --- a/src/client/renderingengine.h +++ b/src/client/renderingengine.h @@ -32,6 +32,7 @@ class Client; class LocalPlayer; class Hud; class Minimap; +class Tracers; class RenderingCore; @@ -117,15 +118,15 @@ public: } inline static void draw_scene(video::SColor skycolor, bool show_hud, - bool show_minimap, bool draw_wield_tool, bool draw_crosshair) + bool show_minimap, bool draw_wield_tool, bool draw_crosshair, bool draw_tracers) { s_singleton->_draw_scene(skycolor, show_hud, show_minimap, - draw_wield_tool, draw_crosshair); + draw_wield_tool, draw_crosshair, draw_tracers); } - inline static void initialize(Client *client, Hud *hud) + inline static void initialize(Client *client, Hud *hud, Tracers *tracers) { - s_singleton->_initialize(client, hud); + s_singleton->_initialize(client, hud, tracers); } inline static void finalize() { s_singleton->_finalize(); } @@ -148,9 +149,9 @@ private: bool clouds = true); void _draw_scene(video::SColor skycolor, bool show_hud, bool show_minimap, - bool draw_wield_tool, bool draw_crosshair); + bool draw_wield_tool, bool draw_crosshair, bool draw_tracers); - void _initialize(Client *client, Hud *hud); + void _initialize(Client *client, Hud *hud, Tracers *tracers); void _finalize(); diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 17129e403..e4871faa1 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -63,7 +63,7 @@ void set_default_settings(Settings *settings) settings->setDefault("max_out_chat_queue_size", "20"); settings->setDefault("pause_on_lost_focus", "false"); settings->setDefault("enable_register_confirmation", "true"); - + // Cheats settings->setDefault("xray", "false"); settings->setDefault("xray_node", "default:stone"); @@ -88,7 +88,12 @@ void set_default_settings(Settings *settings) settings->setDefault("no_night", "false"); settings->setDefault("coords", "false"); settings->setDefault("point_liquids", "false"); - + settings->setDefault("log_particles", "false"); + settings->setDefault("spamclick", "false"); + settings->setDefault("no_force_rotate", "false"); + settings->setDefault("enable_tracers", "false"); + settings->setDefault("no_slow", "false"); + // Keymap settings->setDefault("remote_port", "30000"); settings->setDefault("keymap_forward", "KEY_KEY_W"); diff --git a/src/gui/cheatMenu.h b/src/gui/cheatMenu.h index ff2cec207..e81f9d3b9 100644 --- a/src/gui/cheatMenu.h +++ b/src/gui/cheatMenu.h @@ -42,13 +42,11 @@ public: void draw(video::IVideoDriver* driver, bool show_debug); void drawEntry(video::IVideoDriver* driver, std::string name, int number, bool selected, bool active, CheatMenuEntryType entry_type = CHEAT_MENU_ENTRY_TYPE_ENTRY); - void selectUp(); void selectDown(); void selectLeft(); void selectRight(); void selectConfirm(); - private: bool m_cheat_layer = false; int m_selected_cheat = 0; diff --git a/src/gui/tracers.cpp b/src/gui/tracers.cpp index 6bcbff546..41e241b28 100644 --- a/src/gui/tracers.cpp +++ b/src/gui/tracers.cpp @@ -15,12 +15,27 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ +*/ -#include "tracers.h" +#include +#include "client/client.h" +#include "client/camera.h" +#include "tracers.h" #include "constants.h" -void Tracers::draw(video::IVideoDriver* driver) +void Tracers::draw(video::IVideoDriver* driver, Client *client) { - driver->draw3DLine(v3f(0, 0, 0), v3f(1000, 1000, 1000) * BS, video::SColor(255, 0, 0, 0)); + ClientEnvironment &env = client->getEnv(); + LocalPlayer *player = env.getLocalPlayer(); + Camera *camera = client->getCamera(); + v3f player_pos = player->getPosition(); + v3f head_pos = camera->getPosition() + camera->getDirection(); + std::vector allObjects; + env.getActiveObjects(player_pos, 1000000, allObjects); + for (const auto &allObject : allObjects) { + ClientActiveObject *obj = allObject.obj; + if (obj->isLocalPlayer() || obj->getParent()) + continue; + driver->draw3DLine(head_pos, obj->getPosition(), video::SColor(255, 255, 255, 255)); + } } diff --git a/src/gui/tracers.h b/src/gui/tracers.h index ae987ddf0..58c0d899e 100644 --- a/src/gui/tracers.h +++ b/src/gui/tracers.h @@ -15,7 +15,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ +*/ #pragma once @@ -24,5 +24,5 @@ with this program; if not, write to the Free Software Foundation, Inc., class Tracers { public: - void draw(video::IVideoDriver* driver); + void draw(video::IVideoDriver* driver, Client *client); }; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 9e0b35f53..5c572ee58 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -449,10 +449,10 @@ void Client::handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt) string initialization data } */ - + LocalPlayer *player = m_env.getLocalPlayer(); - bool try_reattach = player && player->isWaitingForReattach(); - + bool try_reattach = player && player->isWaitingForReattach(); + try { u8 type; u16 removed_count, added_count, id; @@ -595,19 +595,19 @@ void Client::handleCommand_Breath(NetworkPacket* pkt) } void Client::handleCommand_MovePlayer(NetworkPacket* pkt) -{ +{ LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); if ((player->getCAO() && player->getCAO()->getParentId()) || player->isWaitingForReattach()) return; - + v3f pos; f32 pitch, yaw; *pkt >> pos >> pitch >> yaw; - player->setPosition(pos); + player->setLegitPosition(pos); infostream << "Client got TOCLIENT_MOVE_PLAYER" << " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")" @@ -621,6 +621,10 @@ void Client::handleCommand_MovePlayer(NetworkPacket* pkt) it would just force the pitch and yaw values to whatever the camera points to. */ + + if (g_settings->getBool("no_force_rotate")) + return; + ClientEvent *event = new ClientEvent(); event->type = CE_PLAYER_FORCE_MOVE; event->player_force_move.pitch = pitch; @@ -978,6 +982,11 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt) event->type = CE_SPAWN_PARTICLE; event->spawn_particle = new ParticleParameters(p); + + if (g_settings->getBool("log_particles")) { + std::cout << p.pos.X << " " << p.pos.Y << " " << p.pos.Z << std::endl; + } + m_client_event_queue.push(event); } @@ -1175,7 +1184,7 @@ void Client::handleCommand_HudSetFlags(NetworkPacket* pkt) HUD_FLAG_CROSSHAIR_VISIBLE | HUD_FLAG_WIELDITEM_VISIBLE | HUD_FLAG_BREATHBAR_VISIBLE | HUD_FLAG_MINIMAP_VISIBLE | HUD_FLAG_MINIMAP_RADAR_VISIBLE; - + m_minimap_disabled_by_server = !(player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE); bool m_minimap_radar_disabled_by_server = !(player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE); @@ -1189,7 +1198,7 @@ void Client::handleCommand_HudSetFlags(NetworkPacket* pkt) // Switch to surface mode if radar disabled by server if (m_minimap && m_minimap_radar_disabled_by_server && was_minimap_radar_visible) m_minimap->setMinimapMode(MINIMAP_MODE_SURFACEx1); - + } diff --git a/src/script/cpp_api/s_cheats.cpp b/src/script/cpp_api/s_cheats.cpp index 73183c64e..3483640ec 100644 --- a/src/script/cpp_api/s_cheats.cpp +++ b/src/script/cpp_api/s_cheats.cpp @@ -15,14 +15,14 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ +*/ #include "cpp_api/s_cheats.h" #include "cpp_api/s_base.h" #include "cpp_api/s_internal.h" #include "settings.h" -ScriptApiCheatsCheat::ScriptApiCheatsCheat(const std::string &name, const std::string &setting) : +ScriptApiCheatsCheat::ScriptApiCheatsCheat(const std::string &name, const std::string &setting) : m_name(name), m_setting(setting), m_function_ref(0) @@ -30,7 +30,7 @@ ScriptApiCheatsCheat::ScriptApiCheatsCheat(const std::string &name, const std::s } -ScriptApiCheatsCheat::ScriptApiCheatsCheat(const std::string &name, const int &function) : +ScriptApiCheatsCheat::ScriptApiCheatsCheat(const std::string &name, const int &function) : m_name(name), m_setting(""), m_function_ref(function) @@ -41,13 +41,13 @@ bool ScriptApiCheatsCheat::is_enabled() { try { return ! m_function_ref && g_settings->getBool(m_setting); - } catch (SettingNotFoundException) { + } catch (SettingNotFoundException &) { return false; } } void ScriptApiCheatsCheat::toggle(lua_State *L, int error_handler) -{ +{ if (m_function_ref) { lua_rawgeti(L, LUA_REGISTRYINDEX, m_function_ref); lua_pcall(L, 0, 0, error_handler); @@ -93,7 +93,7 @@ ScriptApiCheats::~ScriptApiCheats() void ScriptApiCheats::init_cheats() { SCRIPTAPI_PRECHECKHEADER - + lua_getglobal(L, "core"); lua_getfield(L, -1, "cheats"); if (! lua_istable(L, -1)) { @@ -116,10 +116,10 @@ void ScriptApiCheats::init_cheats() void ScriptApiCheats::toggle_cheat(ScriptApiCheatsCheat *cheat) { SCRIPTAPI_PRECHECKHEADER - + PUSH_ERROR_HANDLER(L); int error_handler = lua_gettop(L) - 1; lua_insert(L, error_handler); - + cheat->toggle(L, error_handler); } diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp index 04ac7fc81..8664d40c9 100644 --- a/src/script/cpp_api/s_security.cpp +++ b/src/script/cpp_api/s_security.cpp @@ -286,9 +286,10 @@ void ScriptApiSecurity::initializeSecurityClient() lua_State *L = getStack(); int thread = getThread(L); - // Backup globals to the registry - lua_getglobal(L, "_G"); - lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP); + + // Backup globals to the registry + lua_getglobal(L, "_G"); + lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP); // create an empty environment createEmptyEnv(L); @@ -321,7 +322,6 @@ void ScriptApiSecurity::initializeSecurityClient() lua_setfield(L, -3, "debug"); lua_pop(L, 1); // Pop old debug - #if USE_LUAJIT // Copy safe jit functions, if they exist lua_getglobal(L, "jit"); diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp index 5d0ccf2e0..fffbc2f1e 100644 --- a/src/script/lua_api/l_client.cpp +++ b/src/script/lua_api/l_client.cpp @@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "map.h" #include "util/string.h" #include "nodedef.h" +#include "client/keycode.h" #define checkCSMRestrictionFlag(flag) \ ( getClient(L)->checkCSMRestrictionFlag(CSMRestrictionFlags::flag) ) @@ -420,7 +421,7 @@ int ModApiClient::l_send_damage(lua_State *L) { u16 damage = luaL_checknumber(L, 1); getClient(L)->sendDamage(damage); - return 0; + return 0; } // place_node(pos) @@ -463,17 +464,35 @@ int ModApiClient::l_get_inventory(lua_State *L) InventoryLocation inventory_location; Inventory *inventory; std::string location; - + location = readParam(L, 1); try { inventory_location.deSerialize(location); inventory = client->getInventory(inventory_location); push_inventory(L, inventory); - } catch (SerializationError) { + } catch (SerializationError &) { lua_pushnil(L); } - + + return 1; +} + +// set_keypress(key_setting, pressed) -> returns true on success +int ModApiClient::l_set_keypress(lua_State *L) +{ + std::string setting_name = "keymap_" + readParam(L, 1); + bool pressed = lua_isboolean(L, 2) && readParam(L, 2); + try { + KeyPress keyCode = getKeySetting(setting_name.c_str()); + if (pressed) + g_game->input->setKeypress(keyCode); + else + g_game->input->unsetKeypress(keyCode); + lua_pushboolean(L, true); + } catch (SettingNotFoundException &) { + lua_pushboolean(L, false); + } return 1; } @@ -508,4 +527,5 @@ void ModApiClient::Initialize(lua_State *L, int top) API_FCT(place_node); API_FCT(dig_node); API_FCT(get_inventory); + API_FCT(set_keypress); } diff --git a/src/script/lua_api/l_client.h b/src/script/lua_api/l_client.h index 21a540f8f..e1156b4f5 100644 --- a/src/script/lua_api/l_client.h +++ b/src/script/lua_api/l_client.h @@ -104,18 +104,21 @@ private: // get_csm_restrictions() static int l_get_csm_restrictions(lua_State *L); - + // send_damage(damage) static int l_send_damage(lua_State *L); - + // place_node(pos) static int l_place_node(lua_State *L); - + // dig_node(pos) static int l_dig_node(lua_State *L); - + // get_inventory(location) static int l_get_inventory(lua_State *L); -public: + + // l_set_keypress(key_setting, pressed) + static int l_set_keypress(lua_State *L); +public: static void Initialize(lua_State *L, int top); }; diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 2ea3b08b9..7936ef407 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -825,13 +825,13 @@ int ModApiEnvMod::l_find_nodes_near(lua_State *L) if (Client *client = getClient(L)) radius = client->CSMClampRadius(pos, radius); #endif - + std::vector individual_count; individual_count.resize(filter.size()); - + lua_newtable(L); u32 i = 0; - + for (int d = start_radius; d <= radius; d++) { const std::vector &list = FacePositionCache::getFacePositions(d); for (const v3s16 &posi : list) { @@ -875,13 +875,13 @@ int ModApiEnvMod::l_find_nodes_near_under_air(lua_State *L) if (Client *client = getClient(L)) radius = client->CSMClampRadius(pos, radius); #endif - + std::vector individual_count; individual_count.resize(filter.size()); - + lua_newtable(L); u32 i = 0; - + for (int d = start_radius; d <= radius; d++) { const std::vector &list = FacePositionCache::getFacePositions(d); for (const v3s16 &posi : list) { @@ -929,13 +929,13 @@ int ModApiEnvMod::l_find_nodes_near_under_air_except(lua_State *L) if (Client *client = getClient(L)) radius = client->CSMClampRadius(pos, radius); #endif - + std::vector individual_count; individual_count.resize(filter.size()); - + lua_newtable(L); u32 i = 0; - + for (int d = start_radius; d <= radius; d++) { const std::vector &list = FacePositionCache::getFacePositions(d); for (const v3s16 &posi : list) { @@ -1365,7 +1365,7 @@ int ModApiEnvMod::l_delete_area(lua_State *L) // max_jump, max_drop, algorithm) -> table containing path int ModApiEnvMod::l_find_path(lua_State *L) { - GET_ENV_PTR; + Environment *env = getEnv(L); v3s16 pos1 = read_v3s16(L, 1); v3s16 pos2 = read_v3s16(L, 2); @@ -1383,7 +1383,7 @@ int ModApiEnvMod::l_find_path(lua_State *L) algo = PA_DIJKSTRA; } - std::vector path = get_path(&env->getServerMap(), env->getGameDef()->ndef(), pos1, pos2, + std::vector path = get_path(&env->getMap(), env->getGameDef()->ndef(), pos1, pos2, searchdistance, max_jump, max_drop, algo); if (!path.empty()) { @@ -1568,6 +1568,7 @@ void ModApiEnvMod::InitializeClient(lua_State *L, int top) API_FCT(find_nodes_near_under_air_except); API_FCT(find_nodes_in_area); API_FCT(find_nodes_in_area_under_air); + API_FCT(find_path); API_FCT(line_of_sight); API_FCT(raycast); } diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp index 55c62ab0f..8d94702aa 100644 --- a/src/script/lua_api/l_localplayer.cpp +++ b/src/script/lua_api/l_localplayer.cpp @@ -62,6 +62,24 @@ int LuaLocalPlayer::l_get_velocity(lua_State *L) return 1; } +int LuaLocalPlayer::l_set_velocity(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + v3f pos = checkFloatPos(L, 2); + player->setSpeed(pos); + + return 0; +} + +int LuaLocalPlayer::l_get_yaw(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushinteger(L, player->getYaw()); + return 1; +} + int LuaLocalPlayer::l_get_hp(lua_State *L) { LocalPlayer *player = getobject(L, 1); @@ -502,6 +520,7 @@ void LuaLocalPlayer::Register(lua_State *L) const char LuaLocalPlayer::className[] = "LocalPlayer"; const luaL_Reg LuaLocalPlayer::methods[] = { luamethod(LuaLocalPlayer, get_velocity), + luamethod(LuaLocalPlayer, set_velocity), luamethod(LuaLocalPlayer, get_hp), luamethod(LuaLocalPlayer, get_name), luamethod(LuaLocalPlayer, get_wield_index), @@ -525,6 +544,7 @@ const luaL_Reg LuaLocalPlayer::methods[] = { luamethod(LuaLocalPlayer, get_breath), luamethod(LuaLocalPlayer, get_pos), luamethod(LuaLocalPlayer, set_pos), + luamethod(LuaLocalPlayer, get_yaw), luamethod(LuaLocalPlayer, set_yaw), luamethod(LuaLocalPlayer, set_pitch), luamethod(LuaLocalPlayer, get_movement_acceleration), diff --git a/src/script/lua_api/l_localplayer.h b/src/script/lua_api/l_localplayer.h index fd8d065ba..c4bd4553b 100644 --- a/src/script/lua_api/l_localplayer.h +++ b/src/script/lua_api/l_localplayer.h @@ -35,6 +35,9 @@ private: // get_velocity(self) static int l_get_velocity(lua_State *L); + // set_velocity(self, vel) + static int l_set_velocity(lua_State *L); + // get_hp(self) static int l_get_hp(lua_State *L); @@ -75,8 +78,13 @@ private: // get_pos(self) static int l_get_pos(lua_State *L); + + // set_pos(self, pos) static int l_set_pos(lua_State *L); + // get_yaw(self) + static int l_get_yaw(lua_State *L); + static int l_set_yaw(lua_State *L); static int l_set_pitch(lua_State *L); diff --git a/textures/texture_packs_here.txt b/textures/texture_packs_here.txt new file mode 100644 index 000000000..4c9afe18e --- /dev/null +++ b/textures/texture_packs_here.txt @@ -0,0 +1 @@ +Put your texture pack folders in this folder. Textures in the "server" pack will be used by the server. diff --git a/util/buildbot/buildwin32.sh b/util/buildbot/buildwin32.sh index 935d8c642..a4238fbd8 100755 --- a/util/buildbot/buildwin32.sh +++ b/util/buildbot/buildwin32.sh @@ -6,7 +6,7 @@ CORE_BRANCH=master CORE_NAME=dragonfireclient GAME_GIT=https://git.minetest.land/Wuzzy/MineClone2 GAME_BRANCH=master -GAME_NAME=MineClone2 +GAME_NAME=mineclone2 dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" if [ $# -ne 1 ]; then diff --git a/util/buildbot/buildwin64.sh b/util/buildbot/buildwin64.sh index 9f38b6dc0..1b680cf5b 100755 --- a/util/buildbot/buildwin64.sh +++ b/util/buildbot/buildwin64.sh @@ -6,7 +6,7 @@ CORE_BRANCH=master CORE_NAME=dragonfireclient GAME_GIT=https://git.minetest.land/Wuzzy/MineClone2 GAME_BRANCH=master -GAME_NAME=MineClone2 +GAME_NAME=mineclone2 dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" if [ $# -ne 1 ]; then