diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9d0a011 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "Lua.diagnostics.globals": [ + "rp_nodes", + "minetest", + "rp_core", + "VoxelArea", + "vector", + "VoxelManip", + "dump", + "ItemStack" + ] +} \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..d6942b5 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +## License of the code + Copyright (C) 2023 1F616EMO + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +## License of media +All of them are CC BY-SA 4.0 or later unless other specified. + +License URl: https://creativecommons.org/licenses/by-sa/4.0/ \ No newline at end of file diff --git a/README.md b/README.md index f8703e7..8a640ca 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# r_place \ No newline at end of file +# r/place on Minetest + +This game provids a canvas for pixel painting. Inspired by [Minetest r/place mod on Reddit](https://www.reddit.com/r/Minetest/comments/1608nhe/minetest_rplace_mod/), but not taking any source codes from it. diff --git a/game.conf b/game.conf new file mode 100644 index 0000000..12e5cdc --- /dev/null +++ b/game.conf @@ -0,0 +1,5 @@ +name = r_place +title = rPlace +description = Reddit place in Minetest +allowed_mapgens = singlenode +disabled_settings = enable_damage, !creative_mode \ No newline at end of file diff --git a/LICENSE b/lgpl-2.1.txt similarity index 100% rename from LICENSE rename to lgpl-2.1.txt diff --git a/menu/icon.png b/menu/icon.png new file mode 100644 index 0000000..2abf64b Binary files /dev/null and b/menu/icon.png differ diff --git a/mods/rp_core/border.lua b/mods/rp_core/border.lua new file mode 100644 index 0000000..d8a6416 --- /dev/null +++ b/mods/rp_core/border.lua @@ -0,0 +1,183 @@ +-- r_place/mods/rp_core/mapgen.lua +-- Handle border generation +--[[ + Copyright (C) 2023 1F616EMO + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA +]] + +local function v(x,z) + return vector.new(x,1,z) +end + +local WP = minetest.get_worldpath() +local NEW_BORDER +-- ^%s*%(%s*([^%s,]+)%s*[,%s]%s*([^%s,]+)%s*[,%s]?%s*%)() +do + local BORDER_POS1_SETTINGS = minetest.settings:get("r_place.area_pos1") or "(30,30)" + local BORDER_POS2_SETTINGS = minetest.settings:get("r_place.area_pos2") or "(-30,-30)" + + local BORDER_POS1x, BORDER_POS1z = string.match( + BORDER_POS1_SETTINGS, + "^%s*%(%s*([^%s,]+)%s*[,%s]%s*([^%s,]+)%s*[,%s]?%s*%)()" + ) + local BORDER_POS2x, BORDER_POS2z = string.match( + BORDER_POS2_SETTINGS, + "^%s*%(%s*([^%s,]+)%s*[,%s]%s*([^%s,]+)%s*[,%s]?%s*%)()" + ) + + BORDER_POS1x, BORDER_POS1z = tonumber(BORDER_POS1x), tonumber(BORDER_POS1z) + BORDER_POS2x, BORDER_POS2z = tonumber(BORDER_POS2x), tonumber(BORDER_POS2z) + + if not (BORDER_POS1x and BORDER_POS1z and BORDER_POS2x and BORDER_POS2z) then + error("[rp_core] Please pass valid coordinates into r_place.area_pos{1,2}!") + end + + NEW_BORDER = { + { + BORDER_POS1x < BORDER_POS2x and BORDER_POS1x or BORDER_POS2x, + BORDER_POS1z < BORDER_POS2z and BORDER_POS1z or BORDER_POS2z + }, { + BORDER_POS1x >= BORDER_POS2x and BORDER_POS1x or BORDER_POS2x, + BORDER_POS1z >= BORDER_POS2z and BORDER_POS1z or BORDER_POS2z + } + } +end + +rp_core.area = NEW_BORDER + +minetest.after(0,function() + do -- Clear old barrier and remove out-of-range nodes + local CACHE_PATH = WP .. "/" .. "rp_core_border_cache" + local CACHE_READ = io.open(CACHE_PATH, "r") + if CACHE_READ then + local OLD_BORDER = minetest.deserialize(CACHE_READ:read("*a")) + if OLD_BORDER + and (OLD_BORDER[1][1] ~= NEW_BORDER[1][1] + or OLD_BORDER[1][2] ~= NEW_BORDER[1][2] + or OLD_BORDER[2][1] ~= NEW_BORDER[2][1] + or OLD_BORDER[2][2] ~= NEW_BORDER[2][2]) then + -- Not equal + rp_core.log("action","Removing old area barriers...") + local remove_queue = {} + + -- Remove building nodes + for x = OLD_BORDER[1][1], OLD_BORDER[2][1], 1 do + for z = OLD_BORDER[1][2], OLD_BORDER[2][2], 1 do + if x < NEW_BORDER[1][1] + or x > NEW_BORDER[2][1] + or z < NEW_BORDER[1][2] + or z > NEW_BORDER[2][2] then + table.insert(remove_queue,{x,z}) + end + end + end + + -- Remove old border + for x = OLD_BORDER[1][1] - 1, OLD_BORDER[2][1] + 1, 1 do + table.insert(remove_queue,{x,OLD_BORDER[1][2] - 1}) + table.insert(remove_queue,{x,OLD_BORDER[2][2] + 1}) + end + for z = OLD_BORDER[1][2] - 1, OLD_BORDER[2][2] + 1, 1 do + table.insert(remove_queue,{OLD_BORDER[1][1] - 1,z}) + table.insert(remove_queue,{OLD_BORDER[2][1] + 1,z}) + end + + local VM = VoxelManip() + local pmin, pmax = VM:read_from_map( + v(OLD_BORDER[1][1] - 1,OLD_BORDER[1][2] - 1), + v(OLD_BORDER[2][1] + 1,OLD_BORDER[2][2] + 1) + ) + local data = VM:get_data() + local VA = VoxelArea(pmin,pmax) + + for _,pos in pairs(remove_queue) do + local vm_i = VA:index(pos[1],1,pos[2]) + data[vm_i] = minetest.CONTENT_AIR + end + + VM:set_data(data) + VM:calc_lighting() + VM:write_to_map() + + minetest.after(1,minetest.fix_light,pmin,pmax) + end + CACHE_READ:close() + end + -- Write back to cache + local CACHE_WRITE = io.open(CACHE_PATH, "w") + if CACHE_WRITE then + CACHE_WRITE:write(minetest.serialize(NEW_BORDER)) + CACHE_WRITE:close() + end + end + + do -- Construct area + rp_core.log("action","Constructing area") + local CONTENT_BORDER = minetest.get_content_id("rp_mapgen_nodes:border") + local CONTENT_FILL = minetest.get_content_id("rp_mapgen_nodes:default_fill") + local CONTENT_AIR = minetest.CONTENT_AIR + local CONTENT_IGNORE = minetest.CONTENT_IGNORE + + local VM = VoxelManip() + local pmin, pmax = VM:read_from_map( + v(NEW_BORDER[1][1] - 1,NEW_BORDER[1][2] - 1), + v(NEW_BORDER[2][1] + 1,NEW_BORDER[2][2] + 1) + ) + local data = VM:get_data() + local VA = VoxelArea(pmin,pmax) + + for vm_i, d in ipairs(data) do + local pos = VA:position(vm_i) + local x,y,z = pos.x, pos.y, pos.z + if y ~= 1 + or x < NEW_BORDER[1][1] - 1 + or x > NEW_BORDER[2][1] + 1 + or z < NEW_BORDER[1][2] - 1 + or z > NEW_BORDER[2][2] + 1 then + data[vm_i] = CONTENT_IGNORE + elseif x == NEW_BORDER[1][1] - 1 + or x == NEW_BORDER[2][1] + 1 + or z == NEW_BORDER[1][2] - 1 + or z == NEW_BORDER[2][2] + 1 then + data[vm_i] = CONTENT_BORDER + elseif d == CONTENT_AIR + or d == CONTENT_IGNORE + or d == CONTENT_BORDER then + data[vm_i] = CONTENT_FILL + else + data[vm_i] = CONTENT_IGNORE + end + end + + VM:set_data(data) + VM:write_to_map() + + minetest.after(1,minetest.fix_light,pmin,pmax) + end +end) + +function rp_core.in_area(pos) + local x, y, z = pos.x, pos.y, pos.z + if y ~= 1 + or x < rp_core.area[1][1] + or x > rp_core.area[2][1] + or z < rp_core.area[1][2] + or z > rp_core.area[2][2] then + return false + end + return true +end \ No newline at end of file diff --git a/mods/rp_core/commands.lua b/mods/rp_core/commands.lua new file mode 100644 index 0000000..f120e0d --- /dev/null +++ b/mods/rp_core/commands.lua @@ -0,0 +1,61 @@ +-- r_place/mods/rp_core/commands.lua +-- Handle chatcommands +--[[ + Copyright (C) 2023 1F616EMO + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA +]] + +local S = minetest.get_translator("rp_core") + +do + local CONTENT_IGNORE = minetest.CONTENT_IGNORE + local CONTENT_FILL = minetest.get_content_id("rp_mapgen_nodes:default_fill") + + minetest.register_chatcommand("reset",{ + description = S("Reset the area"), + privs = {server = true}, + func = function(name,param) + local VM = VoxelManip() + local minp, maxp = VM:read_from_map( + { + x = rp_core.area[1][1], + y = 1, + z = rp_core.area[1][2] + }, { + x = rp_core.area[2][1], + y = 1, + z = rp_core.area[2][2] + }) + local VA = VoxelArea(minp, maxp) + local data = {} + for i in VA:iterp(minp, maxp) do + local pos = VA:position(i) + if rp_core.in_area(pos) then + data[i] = CONTENT_FILL + else + data[i] = CONTENT_IGNORE + end + end + + VM:set_data(data) + VM:write_to_map() + + minetest.after(0,minetest.fix_light,minp,maxp) + return true, "Map reset" + end + }) +end \ No newline at end of file diff --git a/mods/rp_core/init.lua b/mods/rp_core/init.lua new file mode 100644 index 0000000..d20fd19 --- /dev/null +++ b/mods/rp_core/init.lua @@ -0,0 +1,41 @@ +-- r_place/mods/rp_core/init.lua +-- Handle area and node placement +--[[ + Copyright (C) 2023 1F616EMO + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA +]] + +rp_core = {} + +function rp_core.log(lvl,msg) + return minetest.log(lvl,"[rp_core] " .. msg) +end + +local MP = minetest.get_modpath("rp_core") + +local scripts = { + "player", + "mapgen", + "border", + "placement", + "commands", +} + +for _,n in ipairs(scripts) do + dofile(MP .. "/" .. n .. ".lua") +end + diff --git a/mods/rp_core/mapgen.lua b/mods/rp_core/mapgen.lua new file mode 100644 index 0000000..d9586b3 --- /dev/null +++ b/mods/rp_core/mapgen.lua @@ -0,0 +1,42 @@ +-- r_place/mods/rp_core/mapgen.lua +-- Handle area generation +-- With code from langton/mods/lg_mapgen/init.lua +--[[ + Copyright (C) 2023 1F616EMO + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA +]] + +minetest.set_mapgen_setting("mgname", "singlenode", true) + +local ID_GROUND = minetest.get_content_id("rp_mapgen_nodes:transparent_ground") + +minetest.register_on_generated(function(minp,maxp,seed) + if minp.y > 0 or maxp.y < 0 then return end + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) + local data = vm:get_data() + local y = 0 + for z = minp.z, maxp.z do + for x = minp.x, maxp.x do + data[area:index(x,y,z)] = ID_GROUND + end + end + + vm:set_data(data) + vm:calc_lighting() + vm:write_to_map(data) +end) \ No newline at end of file diff --git a/mods/rp_core/mod.conf b/mods/rp_core/mod.conf new file mode 100644 index 0000000..8fd47c1 --- /dev/null +++ b/mods/rp_core/mod.conf @@ -0,0 +1,4 @@ +name = rp_core +title = Place: Core +description = Handle area and node placement +depends = rp_nodes, rp_mapgen_nodes \ No newline at end of file diff --git a/mods/rp_core/placement.lua b/mods/rp_core/placement.lua new file mode 100644 index 0000000..03e2eca --- /dev/null +++ b/mods/rp_core/placement.lua @@ -0,0 +1,101 @@ +-- r_place/mods/rp_core/placement.lua +-- Handle node placement and area protection +--[[ + Copyright (C) 2023 1F616EMO + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA +]] + +local deny = {} +local deny_clear = {} +local delay_hud = {} + +rp_core.time_delay = tonumber(minetest.settings:get("r_place.delay") or "5") or 5 +local time_delay = rp_core.time_delay + +local S = minetest.get_translator("rp_core") + +minetest.register_privilege("no_delay", { + description = S("Disable build delay"), + give_to_singleplayer = false, +}) + +do + local old_is_protected = minetest.is_protected + function minetest.is_protected(pos, name) + if deny[name] and (os.time() - deny[name] <= time_delay) then + return true + elseif not rp_core.in_area(pos) then + return true + end + return old_is_protected(pos, name) + end +end + +local function hud_loop() + local now = os.time() + for _, player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local text = "" + if deny[name] then + text = string.format("%d seconds left", time_delay + (deny[name] - now)) + end + if not delay_hud[name] then + delay_hud[name] = player:hud_add({ + hud_elem_type = "text", + position = {x = 1, y = 0}, + scale = {x = 100, y = 100}, + text = text, + number = 0xFFFFFF, + offset = {x = -6, y = 25}, + alignment = {x = -1, y = 3} + }) + else + player:hud_change(delay_hud[name], "text", text) + end + end + minetest.after(0.5,hud_loop) +end +minetest.after(0,hud_loop) + + +minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing) + if not placer:is_player() then return true end + local name = placer:get_player_name() + if deny_clear[name] then + deny_clear[name]:cancel() + end + if minetest.check_player_privs(name, {no_delay = true}) then + return true + end + deny[name] = os.time() + deny_clear[name] = minetest.after(time_delay, function() + deny[name] = nil + deny_clear[name] = nil + end) + return true +end) + +minetest.register_on_leaveplayer(function(player, timed_out) + local name = player:get_player_name() + deny[name] = nil + delay_hud[name] = nil + if deny_clear[name] then + deny_clear[name]:cancel() + deny_clear[name] = nil + end +end) + diff --git a/mods/rp_core/player.lua b/mods/rp_core/player.lua new file mode 100644 index 0000000..46568fa --- /dev/null +++ b/mods/rp_core/player.lua @@ -0,0 +1,60 @@ +-- r_place/mods/rp_core/player.lua +-- Player spawnpoint and hand +--[[ + Copyright (C) 2023 1F616EMO + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA +]] + +function minetest.get_spawn_level(x,z) + return 10 +end + +local list_nodes = {} +for name, def in pairs(minetest.registered_nodes) do + if def.groups and def.groups.rp_nodes == 1 then + list_nodes[#list_nodes + 1] = ItemStack(name) + end +end + +local inventory_formspec = table.concat({ + "size[8,4]", + "list[current_player;main;0,0;8,4;]" +}, "") + +minetest.register_on_joinplayer(function(player, last_login) + local name = player:get_player_name() + + -- Spawnpoint + local spawn_pos = { + x = (rp_core.area[1][1] + rp_core.area[2][1]) / 2, + y = 10, + z = (rp_core.area[1][2] + rp_core.area[2][2]) / 2 + } + player:set_pos(spawn_pos) + + -- Fly + local privs = minetest.get_player_privs(name) + privs.fly = true + minetest.set_player_privs(name,privs) + + -- Initial items + local inv = player:get_inventory() + inv:set_list("main",list_nodes) + + -- Formspec + player:set_inventory_formspec(inventory_formspec) +end) \ No newline at end of file diff --git a/mods/rp_initial_message/init.lua b/mods/rp_initial_message/init.lua new file mode 100644 index 0000000..d61dde5 --- /dev/null +++ b/mods/rp_initial_message/init.lua @@ -0,0 +1,34 @@ +-- r_place/mods/rp_initial_message/init.lua +-- Send message when a player joins +--[[ + Copyright (C) 2023 1F616EMO + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA +]] + +local S = minetest.get_translator("rp_initial_message") + +local function C(msg) + return minetest.colorize("orange", msg) +end + +minetest.register_on_joinplayer(function(player, last_login) + local name = player:get_player_name() + + minetest.chat_send_player(name, C(S("Welcome to rPlace Minetest Server!"))) + minetest.chat_send_player(name, C(S("Here, you can place pixels to form pictures!"))) + minetest.chat_send_player(name, C(S("All colors are in your inventory; Press `I` to put them onto the hotbar."))) +end) \ No newline at end of file diff --git a/mods/rp_initial_message/mod.conf b/mods/rp_initial_message/mod.conf new file mode 100644 index 0000000..7a8d334 --- /dev/null +++ b/mods/rp_initial_message/mod.conf @@ -0,0 +1,2 @@ +name = rp_initial_message +title = rPlace: Initial Message \ No newline at end of file diff --git a/mods/rp_mapgen_nodes/init.lua b/mods/rp_mapgen_nodes/init.lua new file mode 100644 index 0000000..399acfb --- /dev/null +++ b/mods/rp_mapgen_nodes/init.lua @@ -0,0 +1,54 @@ +-- r_place/mods/rp_mapgen_nodes/init.lua +-- Map generation nodes of Place +--[[ + Copyright (C) 2023 1F616EMO + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA +]] + +minetest.register_node("rp_mapgen_nodes:transparent_ground", { + description = "(Hack!) Transparent Ground", + drawtype = "airlike", + paramtype = "light", + sunlight_propagates = true, + pointable = false, + diggable = false, + is_ground_content = true, + damage_per_second = math.huge, +}) + +minetest.register_node("rp_mapgen_nodes:noplace", { + description = "(Hack!) Place blocker", + drawtype = "airlike", + paramtype = "light", + sunlight_propagates = true, + pointable = false, + diggable = false, + walkable = true, + is_ground_content = true, +}) + +minetest.register_node("rp_mapgen_nodes:border", { + description = "(Hack!) Area Border", + tiles = {"rp_nodes_base.png^[colorize:#000000:255"}, + pointable = true, + diggable = false, + is_ground_content = false, + damage_per_second = math.huge, +}) + +-- Black +minetest.register_alias("rp_mapgen_nodes:default_fill","rp_nodes:color_222222") diff --git a/mods/rp_mapgen_nodes/mod.conf b/mods/rp_mapgen_nodes/mod.conf new file mode 100644 index 0000000..e3b56cb --- /dev/null +++ b/mods/rp_mapgen_nodes/mod.conf @@ -0,0 +1,4 @@ +name = rp_mapgen_nodes +title = Place: Map generation nodes +description = Map generation nodes of Place +depends = rp_nodes \ No newline at end of file diff --git a/mods/rp_nodes/init.lua b/mods/rp_nodes/init.lua new file mode 100644 index 0000000..df77ad4 --- /dev/null +++ b/mods/rp_nodes/init.lua @@ -0,0 +1,74 @@ +-- r_place/mods/rp_nodes/init.lua +-- Nodes for Place +-- With code from parkour/mods/pkr_nodes/init.lua +--[[ + Copyright (C) 2023 1F616EMO + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA +]] + +rp_nodes = {} + +local S = minetest.get_translator("rp_nodes") +rp_nodes.colors = { -- https://lospec.com/palette-list/r-place + ["FFFFFF"] = S("White"), + ["E4E4E4"] = S("Light grey"), + ["888888"] = S("Dark grey"), + ["222222"] = S("Black"), + + ["FFA7D1"] = S("Pink"), + ["E50000"] = S("Red"), + ["E59500"] = S("Orange"), + ["A06A42"] = S("Brown"), + + ["E5D900"] = S("Yellow"), + ["94E044"] = S("Light green"), + ["02BE01"] = S("Green"), + ["00D3DD"] = S("Cyan"), + + ["0083C7"] = S("Light blue"), + ["0000EA"] = S("Blue"), + ["CF6EE4"] = S("Dark pink"), + ["820080"] = S("Magenta"), +} + +local function on_place(itemstack, placer, pointed_thing) + local iname = itemstack:get_name() + local pnode = minetest.get_node(pointed_thing.under) + local pname = pnode.name + if iname ~= pname then + return minetest.item_place(itemstack, placer, pointed_thing) + end + return itemstack, nil +end + +for hex, name in pairs(rp_nodes.colors) do + local alpha = ":200" + if hex == "222222" then + alpha = ":245" + elseif hex == "FFFFFF" then + alpha = ":80" + end + minetest.register_node("rp_nodes:color_" .. hex, { + description = S("@1 building block", name), + tiles = {"rp_nodes_base.png^[colorize:#" .. hex .. alpha}, + groups = {rp_nodes = 1}, + buildable_to = true, + is_ground_content = false, + node_placement_prediction = "", + on_place = on_place, + }) +end \ No newline at end of file diff --git a/mods/rp_nodes/mod.conf b/mods/rp_nodes/mod.conf new file mode 100644 index 0000000..5a665de --- /dev/null +++ b/mods/rp_nodes/mod.conf @@ -0,0 +1,3 @@ +name = rp_nodes +title = Place: Nodes +description = Nodes for Place \ No newline at end of file diff --git a/mods/rp_nodes/textures/rp_nodes_base.png b/mods/rp_nodes/textures/rp_nodes_base.png new file mode 100644 index 0000000..2abf64b Binary files /dev/null and b/mods/rp_nodes/textures/rp_nodes_base.png differ diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..a88e2dd Binary files /dev/null and b/screenshot.png differ diff --git a/settingtypes.txt b/settingtypes.txt new file mode 100644 index 0000000..1431e2d --- /dev/null +++ b/settingtypes.txt @@ -0,0 +1,10 @@ +# Position 1 of r_place. +# Should in the format of (x,y). +r_place.area_pos1 (Place area position 1) string (30,30) + +# Position 2 of r_place. +# Should in the format of (x,y). +r_place.area_pos2 (Place area position 2) string (-30,-30) + +# Delay between placements in seconds +r_place.delay (Delay between placements) int 5 \ No newline at end of file