From a9e6ebb2d7bbb8ea4112d5b1a62bf70a27a79ed5 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Sun, 10 Apr 2022 01:45:19 +0200 Subject: [PATCH] Add basic Perlin noise creator tool --- init.lua | 120 ++++++++++++++++++++++++++- textures/perlin_explorer_creator.png | Bin 0 -> 6439 bytes 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 textures/perlin_explorer_creator.png diff --git a/init.lua b/init.lua index b538678..a2417c4 100644 --- a/init.lua +++ b/init.lua @@ -3,11 +3,13 @@ local COLORIZE_NODES = true local S = minetest.get_translator("perlin_explorer") +local F = minetest.formspec_escape -- Holds the currently used Perlin noise local current_perlin = {} -- holds the current PerlinNoise object current_perlin.noise = nil +current_perlin.noiseparams = {} -- Side length of calculated perlin area current_perlin.size = nil -- Theoretical min and max values for Perlin noise (for colorization) @@ -67,6 +69,13 @@ minetest.register_tool("perlin_explorer:getter", { wield_image = "perlin_explorer_getter.png", groups = { disable_repair = 1 }, on_use = function(itemstack, user, pointed_thing) + if not user then + return + end + local privs = minetest.get_player_privs(user:get_player_name()) + if not privs.server then + minetset.chat_send_player(user:get_player_name(), S("Insufficient privileges! You need the @1 privilege to use this tool.", "server")) + end if current_perlin.noise then if pointed_thing.type ~= "node" then -- No-op for non-nodes @@ -84,7 +93,7 @@ minetest.register_tool("perlin_explorer:getter", { end minetest.chat_send_player(user:get_player_name(), S("pos=@1, value=@2", minetest.pos_to_string(pos), val)) else - local msg = S("No Perlin noise set. Set one with /set_perlin!") + local msg = S("No Perlin noise set. Set one with /set_perlin_noise!") minetest.chat_send_player(user:get_player_name(), msg) end end, @@ -236,6 +245,7 @@ end -- * noiseparams: NoiseParams table (see Minetest's Lua API documentation) local set_perlin_noise = function(noiseparams) current_perlin.noise = PerlinNoise(noiseparams) + current_perlin.noiseparams = noiseparams end minetest.register_chatcommand("perlin_set_options", { @@ -325,4 +335,112 @@ minetest.register_chatcommand("perlin_generate", { end, }) +local show_formspec = function(player) + local offset = tostring(current_perlin.noiseparams.offset or "") + local scale = tostring(current_perlin.noiseparams.scale or "") + local seed = tostring(current_perlin.noiseparams.seed or "") + local sx, sy, sz = "", "", "" + if current_perlin.noiseparams.spread then + sx = tostring(current_perlin.noiseparams.spread.x or "") + sy = tostring(current_perlin.noiseparams.spread.y or "") + sz = tostring(current_perlin.noiseparams.spread.z or "") + end + local octaves = tostring(current_perlin.noiseparams.octaves or "") + local persistence = tostring(current_perlin.noiseparams.persistence or "") + local lacunarity = tostring(current_perlin.noiseparams.lacunarity or "") + -- TODO: Add 3D + -- TODO: Add pos + -- TODO: Add noise options + local form = [[ + formspec_version[4]size[10,10] + field[0.5,0.5;3,0.75;offset;]]..F(S("Offset"))..[[;]]..offset..[[] + field[3.5,0.5;3,0.75;scale;]]..F(S("Scale"))..[[;]]..scale..[[] + field[6.5,0.5;3,0.75;seed;]]..F(S("Seed"))..[[;]]..seed..[[] + field[0.5,1.75;3,0.75;spread_x;]]..F(S("X Spread"))..[[;]]..sx..[[] + field[3.5,1.75;3,0.75;spread_y;]]..F(S("Y Spread"))..[[;]]..sy..[[] + field[6.5,1.75;3,0.75;spread_z;]]..F(S("Z Spread"))..[[;]]..sz..[[] + field[0.5,3;3,0.75;octaves;]]..F(S("Octaves"))..[[;]]..octaves..[[] + field[3.5,3;3,0.75;persistence;]]..F(S("Persistence"))..[[;]]..persistence..[[] + field[6.5,3;3,0.75;lacunarity;]]..F(S("Lacunarity"))..[[;]]..lacunarity..[[] + + field_close_on_enter[offset;false] + field_close_on_enter[scale;false] + field_close_on_enter[seed;false] + field_close_on_enter[spread_x;false] + field_close_on_enter[spread_y;false] + field_close_on_enter[spread_z;false] + field_close_on_enter[octaves;false] + field_close_on_enter[persistence;false] + field_close_on_enter[lacunarity;false] + + label[0.5,4.5;]]..F(S("Dimensions"))..[[] + dropdown[3.5,4.5;3;dimensions;]]..F(S("2D"))..[[;1;true] + + button[0.5,8.5;3,1;apply;]]..F(S("Apply"))..[[] + button[3.5,8.5;3,1;create;]]..F(S("Apply and create"))..[[] + button_exit[6.5,8.5;3,1;close;]]..F(S("Close"))..[[] + ]] + minetest.show_formspec(player:get_player_name(), "perlin_explorer:creator", form) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "perlin_explorer:creator" then + return + end + local do_apply = fields.apply ~= nil + local do_create = fields.create ~= nil or fields.key_enter_field ~= nil + if (do_create or do_apply) then + if fields.offset and fields.scale and fields.seed and fields.spread_x and fields.spread_y and fields.spread_z and fields.octaves and fields.persistence and fields.lacunarity then + local offset = tonumber(fields.offset) + local scale = tonumber(fields.scale) + local seed = tonumber(fields.seed) + local sx = tonumber(fields.spread_x) + local sy = tonumber(fields.spread_y) + local sz = tonumber(fields.spread_z) + local spread = vector.new(sx, sy, sz) + local octaves = tonumber(fields.octaves) + local persistence = tonumber(fields.persistence) + local lacunarity = tonumber(fields.lacunarity) + local dimensions = 2 -- TODO + if not (offset and scale and spread_x and spread_y and spread_z and octaves and persistence and dimensions) then + set_perlin_noise({ + offset = offset, + scale = scale, + seed = seed, + spread = spread, + octaves = octaves, + persistence = persistence, + lacunarity = lacunarity, + }) + if do_create then + local pos = player:get_pos() + pos.y = pos.y - 10 + local msg = create_perlin(pos, {dimensions=dimensions, size=64}) + if msg == false then + minetest.log("error", "[perlin_explorer] Error generating Perlin noise nodes!") + end + end + end + end + end +end) + +minetest.register_tool("perlin_explorer:creator", { + description = S("Perlin Noise Creator"), + _tt_help = S("Punch to open the Perlin noise creation menu"), + inventory_image = "perlin_explorer_creator.png", + wield_image = "perlin_explorer_creator.png", + groups = { disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + if not user then + return + end + local privs = minetest.get_player_privs(user:get_player_name()) + if not privs.server then + minetset.chat_send_player(user:get_player_name(), S("Insufficient privileges! You need the @1 privilege to use this tool.", "server")) + end + show_formspec(user) + end, +}) + diff --git a/textures/perlin_explorer_creator.png b/textures/perlin_explorer_creator.png new file mode 100644 index 0000000000000000000000000000000000000000..2e7b03f2e912e5bf0a62c8946d4f2ad11f7d87d7 GIT binary patch literal 6439 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 literal 0 HcmV?d00001