From d70a251c3bf0b1bfe02f15e828ef029f00768a09 Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Tue, 17 May 2022 06:49:56 +0200 Subject: [PATCH] Initial import --- init.lua | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ mod.conf | 3 + 2 files changed, 221 insertions(+) create mode 100644 init.lua create mode 100644 mod.conf diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..1ecd162 --- /dev/null +++ b/init.lua @@ -0,0 +1,218 @@ +--[[ + +maps – Minetest mod to render very ugly HUD maps +Copyright © 2022 Nils Dagsson Moskopp (erlehmann) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +Dieses Programm hat das Ziel, die Medienkompetenz der Leser zu +steigern. Gelegentlich packe ich sogar einen handfesten Buffer +Overflow oder eine Format String Vulnerability zwischen die anderen +Codezeilen und schreibe das auch nicht dran. + +]]-- + +maps = {} +maps.dots = {} +maps.maps = {} +maps.minp = {} +maps.maxp = {} +maps.work = {} +maps.sent = {} +maps.posx = {} +maps.posz = {} + +local worldpath = minetest.get_worldpath() +local textures_dir = worldpath .. "/maps/" +minetest.mkdir(textures_dir) + +maps.create_map = function(pos, player_name) + local minp = vector.multiply(vector.floor(vector.divide(pos, 64)), 64) + local maxp = vector.add(minp, vector.new(63, 63, 63)) + + local prefix, _ = minetest.pos_to_string(maxp) + prefix, _ = prefix:gsub("%(", "") + prefix, _ = prefix:gsub("%)", "") + prefix, _ = prefix:gsub(",", "_") + local filename = prefix .. ".tga" + + if maps.work[filename] then + return + end + + local player = minetest.get_player_by_name(player_name) + + if maps.sent[filename] then + maps.minp[player_name] = minp + maps.maxp[player_name] = maxp + player:hud_change( + maps.maps[player_name], + "text", + filename + ) + return + end + + maps.work[filename] = true + + player:hud_change( + maps.maps[player_name], + "text", + "blank.png" + ) + + local emerge_callback = function( + blockpos, + action, + calls_remaining + ) + if calls_remaining > 0 then + return + end + + local pixels = {} + local colormap = { + { 0, 0, 0 }, + { 0, 0, 255 }, -- water + { 255, 127, 0 }, -- lava + { 127, 127, 127 }, -- cracky + { 175, 175, 175 }, -- crumbly + { 47, 47, 47 }, -- stone + { 127, 47, 47 }, -- soil + { 0, 255, 0 }, -- grass + { 255, 255, 0 }, -- sand + { 255, 255, 255 }, -- snow + { 0, 47, 0 }, -- leaves + { 255, 0, 0 }, -- fire + } + for x = 1,66,1 do + for z = 1,66,1 do + local color = { 0 } + pixels[z] = pixels[z] or {} + pixels[z][x] = color + end + end + + local color_map = function(color, query) + local positions = minetest.find_nodes_in_area_under_air(minp, maxp, query) + for _, p in ipairs(positions) do + local z = p.z - minp.z + 2 + local x = p.x - minp.x + 2 + pixels[z][x] = { color } + end + end + color_map( 1, "group:water") + color_map( 2, "group:lava") + color_map( 3, "group:cracky") + color_map( 4, "group:crumbly") + color_map( 5, "group:stone") + color_map( 6, "group:soil") + color_map( 7, "group:spreading_dirt_type") + color_map( 8, "group:sand") + color_map( 9, "group:snowy") + color_map(10, "group:leaves") + color_map(11, "group:fire") + + local filepath = textures_dir .. filename + tga_encoder.image(pixels):save( + filepath, + { colormap=colormap } + ) + + minetest.dynamic_add_media( + filepath, + function() + local player =minetest.get_player_by_name(player_name) + player:hud_change( + maps.maps[player_name], + "text", + filename + ) + maps.minp[player_name] = minp + maps.maxp[player_name] = maxp + maps.sent[filename] = true + maps.work[filename] = false + end + ) + end + + minetest.emerge_area( + minp, + maxp, + emerge_callback + ) +end + +minetest.register_on_joinplayer( + function(player) + local player_name = player:get_player_name() + local map_def = { + hud_elem_type = "image", + text = "blank.png", + position = { x = 0.15, y = 0.90 }, + alignment = { x = 0, y = -1 }, + offset = { x = 0, y = 0 }, + scale = { x = 4, y = 4 } + } + local dot_def = table.copy(map_def) + dot_def.text = "player.png^[resize:4x8" + maps.maps[player_name] = player:hud_add(map_def) + maps.dots[player_name] = player:hud_add(dot_def) + maps.minp[player_name] = { x=-32000, y=0, z=0 } + maps.maxp[player_name] = { x=-32000, y=0, z=0 } + end +) + +local time_elapsed = 0 + +minetest.register_globalstep( + function(dtime) + time_elapsed = time_elapsed + dtime + if time_elapsed < ( 1 / 30 ) then + return -- fps limiter + end + local players = minetest.get_connected_players() + for _, player in pairs(players) do + local pos = vector.round(player:get_pos()) + local player_name = player:get_player_name() + + if ( + pos.x == maps.posx[player_name] and + pos.z == maps.posz[player_name] + ) then + -- continue + else + local minp = maps.minp[player_name] + local maxp = maps.maxp[player_name] + + if pos.x < minp.x then + maps.create_map(pos, player_name) + elseif pos.x > maxp.x then + maps.create_map(pos, player_name) + end + + if pos.z < minp.z then + maps.create_map(pos, player_name) + elseif pos.z > maxp.z then + maps.create_map(pos, player_name) + end + + local x = (pos.x - minp.x - 32) * 4 + local y = (minp.z - pos.z) * 4 - 2 + player:hud_change( + maps.dots[player_name], + "offset", + { + x = x, + y = y, + } + ) + maps.posx[player_name] = pos.x + maps.posz[player_name] = pos.z + end + end + end +) diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..eda80f4 --- /dev/null +++ b/mod.conf @@ -0,0 +1,3 @@ +depends = tga_encoder +description = Shows maps in the player HUD +name = maps