From c1d11738095bb9602241364b26b667a32a0893c2 Mon Sep 17 00:00:00 2001 From: Alexsandro Percy Date: Mon, 12 Feb 2024 19:41:23 -0300 Subject: [PATCH] added support for signs_lib --- init.lua | 52 +++++++- lib_planes/entities.lua | 4 +- lib_planes/utilities.lua | 6 + mod.conf | 2 +- settingtypes.txt | 3 + text.lua | 205 ++++++++++++++++++++++++++++++ textures/airutils_name_canvas.png | Bin 0 -> 5526 bytes 7 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 text.lua create mode 100755 textures/airutils_name_canvas.png diff --git a/init.lua b/init.lua index 68871a2..0234987 100644 --- a/init.lua +++ b/init.lua @@ -30,7 +30,6 @@ if(minetest.get_translator ~= nil) then else airutils.S = function ( s ) return s end - end local S = airutils.S @@ -60,6 +59,10 @@ if not minetest.settings:get_bool('airutils_disable_repair') then dofile(minetest.get_modpath("airutils") .. DIR_DELIM .. "airutils_repair.lua") end +airutils._use_signs_api = true +if not minetest.get_modpath("signs_lib") then airutils._use_signs_api = false end +if minetest.settings:get_bool('airutils_disable_signs_api') then airutils._use_signs_api = false end + airutils.get_wind = dofile(minetest.get_modpath("airutils") .. DIR_DELIM ..'/wind.lua') dofile(minetest.get_modpath("airutils") .. DIR_DELIM .. "common_entities.lua") dofile(minetest.get_modpath("airutils") .. DIR_DELIM .. "airutils_wind.lua") @@ -69,6 +72,7 @@ dofile(minetest.get_modpath("airutils") .. DIR_DELIM .. "physics_lib.lua") dofile(minetest.get_modpath("airutils") .. DIR_DELIM .. "lib_planes" .. DIR_DELIM .. "init.lua") dofile(minetest.get_modpath("airutils") .. DIR_DELIM .. "lib_copter" .. DIR_DELIM .. "init.lua") dofile(minetest.get_modpath("airutils") .. DIR_DELIM .. "texture_management.lua") +if airutils._use_signs_api then dofile(minetest.get_modpath("airutils") .. DIR_DELIM .. "text.lua") end local is_biofuel_installed = false if biomass then @@ -451,6 +455,18 @@ function airutils.set_paint(self, puncher, itmstck, texture_name) return false end +function airutils._set_name(self) + if not airutils._use_signs_api then return end + local l_textures = self.object:get_properties().textures --self.initial_properties.textures + for _, texture in ipairs(l_textures) do + indx = texture:find('airutils_name_canvas.png') + if indx then + l_textures[_] = "airutils_name_canvas.png^"..airutils.convert_text_to_texture(self._ship_name, self._name_color or 0, self._name_hor_aligment or 0.8) + end + end + self.object:set_properties({textures=l_textures}) +end + --painting function airutils.paint(self, colstr, texture_name) if not self then return end @@ -615,3 +631,37 @@ minetest.register_chatcommand("show_lift", { end }) +if airutils._use_signs_api then + minetest.register_chatcommand("set_vehicle_name", { + params = "", + description = S("Sets the vehicle name (when supported by the vehicle)"), + privs = {interact = true}, + func = function(name, param) + local colorstring = core.colorize('#ff0000', S(" >>> you are not inside a vehicle")) + local player = minetest.get_player_by_name(name) + local attached_to = player:get_attach() + + if attached_to ~= nil then + local seat = attached_to:get_attach() + if seat ~= nil then + local entity = seat:get_luaentity() + if entity then + if entity.owner == name or minetest.check_player_privs(name, {protection_bypass=true}) then + if param then + entity._ship_name = string.gsub(param, 1,20) + else + entity._ship_name = "" + end + airutils._set_name(entity) + minetest.chat_send_player(name,core.colorize('#00ff00', S(" >>> the vehicle name was changed"))) + else + minetest.chat_send_player(name,core.colorize('#ff0000', S(" >>> only the owner or moderators can name this vehicle"))) + end + end + end + else + minetest.chat_send_player(name,colorstring) + end + end + }) +end diff --git a/lib_planes/entities.lua b/lib_planes/entities.lua index bcfb6fd..830feaf 100644 --- a/lib_planes/entities.lua +++ b/lib_planes/entities.lua @@ -22,7 +22,8 @@ function airutils.get_staticdata(self) -- unloaded/unloads ... is now saved stored_passengers = self._passengers or {}, stored_adf_destiny = self._adf_destiny or vector.new(), stored_skin = self._skin or "", - stored_vehicle_custom_data = self._vehicle_custom_data or nil + stored_vehicle_custom_data = self._vehicle_custom_data or nil, + stored_ship_name = self._ship_name or "", }) end @@ -54,6 +55,7 @@ function airutils.on_activate(self, staticdata, dtime_s) self._passengers = data.stored_passengers or {} self._adf_destiny = data.stored_adf_destiny or vector.new() self._skin = data.stored_skin or "" + self._ship_name = data.stored_ship_name or "" local custom_data = data.stored_vehicle_custom_data or nil if custom_data then self._vehicle_custom_data = custom_data diff --git a/lib_planes/utilities.lua b/lib_planes/utilities.lua index 85e2ade..bf7cd58 100644 --- a/lib_planes/utilities.lua +++ b/lib_planes/utilities.lua @@ -680,6 +680,12 @@ local function _paint(self, l_textures, colstr, paint_list, mask_associations) l_textures[_] = "("..l_textures[_]..")^("..texture_name.."^[mask:"..mask_texture..")" --add the mask end end + if airutils._use_signs_api then + indx = texture:find('airutils_name_canvas.png') + if indx then + l_textures[_] = "airutils_name_canvas.png^"..airutils.convert_text_to_texture(self._ship_name, self._name_color or 0, self._name_hor_aligment or 0.8) + end + end end end return l_textures diff --git a/mod.conf b/mod.conf index a4a24eb..e72d3ab 100644 --- a/mod.conf +++ b/mod.conf @@ -2,4 +2,4 @@ name = airutils title=AirUtils description=A lib for airplanes and some useful tools author=apercy -optional_depends=player_api, emote, climate_api, biofuel +optional_depends=player_api, emote, climate_api, biofuel, signs_lib diff --git a/settingtypes.txt b/settingtypes.txt index b2ebbcc..54fe7cb 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -15,3 +15,6 @@ airutils_disable_repair (planes cannot be repaired) bool false # enable debug od activation and deactivation of the vehicle entity airutils_debug_log (log of entity activation) bool false + +# disable the usage of signs_api by the vehicles +airutils_disable_signs_api (no names writen on vehicles surface) bool false diff --git a/text.lua b/text.lua new file mode 100644 index 0000000..ee12a2c --- /dev/null +++ b/text.lua @@ -0,0 +1,205 @@ +--[[ +License for code: LGPL 3.0 +see at: https://www.gnu.org/licenses/lgpl-3.0.txt + +This code was adapted from signs_lib from VanessaE +the original lib can be found at: https://content.minetest.net/packages/mt-mods/signs_lib/ +]]-- + +-- CONSTANTS + +-- Path to the textures. +local TP = signs_lib.path .. "/textures" +-- Font file formatter +local CHAR_FILE = "%s_%02x.png" +-- Fonts path +local CHAR_PATH = TP .. "/" .. CHAR_FILE + +-- Initialize character texture cache +local ctexcache = {} + +local function fill_line(x, y, w, c, font_size, colorbgw) + c = c or "0" + local tex = { } + for xx = 0, math.max(0, w), colorbgw do + table.insert(tex, (":%d,%d=signs_lib_color_"..font_size.."px_%s.png"):format(x + xx, y, c)) + end + return table.concat(tex) +end + +-- check if a file does exist +-- to avoid reopening file after checking again +-- pass TRUE as second argument +local function file_exists(name, return_handle, mode) + mode = mode or "r"; + local f = io.open(name, mode) + if f ~= nil then + if (return_handle) then + return f + end + io.close(f) + return true + else + return false + end +end + +-- make char texture file name +-- if texture file does not exist use fallback texture instead +local function char_tex(font_name, ch) + if ctexcache[font_name..ch] then + return ctexcache[font_name..ch], true + else + local c = ch:byte() + local exists, tex = file_exists(CHAR_PATH:format(font_name, c)) + if exists and c ~= 14 then + tex = CHAR_FILE:format(font_name, c) + else + tex = CHAR_FILE:format(font_name, 0x0) + end + ctexcache[font_name..ch] = tex + return tex, exists + end +end + +local function make_text_texture(text, default_color, line_width, line_height, cwidth_tab, font_size, colorbgw) + local split = signs_lib.split_lines_and_words + local width = 0 + local maxw = 0 + local font_name = "signs_lib_font_"..font_size.."px" + local text_ansi = Utf8ToAnsi(text) + local text_splited = split(text_ansi)[1] + + local words = { } + default_color = default_color or 0 + + local cur_color = tonumber(default_color, 16) + + -- We check which chars are available here. + for word_i, word in ipairs(text_splited) do + local chars = { } + local ch_offs = 0 + word = string.gsub(word, "%^[12345678abcdefgh]", { + ["^1"] = string.char(0x81), + ["^2"] = string.char(0x82), + ["^3"] = string.char(0x83), + ["^4"] = string.char(0x84), + ["^5"] = string.char(0x85), + ["^6"] = string.char(0x86), + ["^7"] = string.char(0x87), + ["^8"] = string.char(0x88), + ["^a"] = string.char(0x8a), + ["^b"] = string.char(0x8b), + ["^c"] = string.char(0x8c), + ["^d"] = string.char(0x8d), + ["^e"] = string.char(0x8e), + ["^f"] = string.char(0x8f), + ["^g"] = string.char(0x90), + ["^h"] = string.char(0x91) + }) + local word_l = #word + local i = 1 + while i <= word_l do + local c = word:sub(i, i) + if c == "#" then + local cc = tonumber(word:sub(i+1, i+1), 16) + if cc then + i = i + 1 + cur_color = cc + end + else + local w = cwidth_tab[c] + if w then + width = width + w + 1 + if width >= (line_width - cwidth_tab[" "]) then + width = 0 + else + maxw = math.max(width, maxw) + end + local max_input_chars = 20 + if #chars < max_input_chars then + table.insert(chars, { + off = ch_offs, + tex = char_tex(font_name, c), + col = ("%X"):format(cur_color), + }) + end + ch_offs = ch_offs + w + end + end + i = i + 1 + end + width = width + cwidth_tab[" "] + 1 + maxw = math.max(width, maxw) + table.insert(words, { chars=chars, w=ch_offs }) + end + + -- Okay, we actually build the "line texture" here. + + local texture = { } + + local start_xpos = math.floor((line_width - maxw) / 2) + + local xpos = start_xpos + local ypos = line_height + + cur_color = nil + + for word_i, word in ipairs(words) do + local xoffs = (xpos - start_xpos) + if (xoffs > 0) and ((xoffs + word.w) > maxw) then + table.insert(texture, fill_line(xpos, ypos, maxw, "n", font_size, colorbgw)) + xpos = start_xpos + ypos = ypos + line_height + table.insert(texture, fill_line(xpos, ypos, maxw, cur_color, font_size, colorbgw)) + end + for ch_i, ch in ipairs(word.chars) do + if ch.col ~= cur_color then + cur_color = ch.col + table.insert(texture, fill_line(xpos + ch.off, ypos, maxw, cur_color, font_size, colorbgw)) + end + table.insert(texture, (":%d,%d=%s"):format(xpos + ch.off, ypos, ch.tex)) + end + table.insert( + texture, + (":%d,%d="):format(xpos + word.w, ypos) .. char_tex(font_name, " ") + ) + xpos = xpos + word.w + cwidth_tab[" "] + if xpos >= (line_width + cwidth_tab[" "]) then break end + end + + table.insert(texture, fill_line(xpos, ypos, maxw, "n", font_size, colorbgw)) + table.insert(texture, fill_line(start_xpos, ypos + line_height, maxw, "n", font_size, colorbgw)) + + return table.concat(texture) +end + +function airutils.convert_text_to_texture(text, default_color, horizontal_aligment) + default_color = default_color or 0 + horizontal_aligment = horizontal_aligment or 0.8 + local font_size + local line_width + local line_height + local char_width + local colorbgw + local widemult = 1 + text = string.sub(text,1,20) + + --[[font_size = 31 + line_width = math.floor(signs_lib.avgwidth31 * 20) * (1 * widemult) + line_height = signs_lib.lineheight31 + char_width = signs_lib.charwidth31 + colorbgw = signs_lib.colorbgw31]]-- + + font_size = 15 + line_width = math.floor(signs_lib.avgwidth15 * 40) * (horizontal_aligment * widemult) + line_height = signs_lib.lineheight15 + char_width = signs_lib.charwidth15 + colorbgw = signs_lib.colorbgw15 + + local texture = { ("[combine:%dx%d"):format(line_width, line_height) } + local linetex = make_text_texture(text, default_color, line_width, line_height, char_width, font_size, colorbgw) + table.insert(texture, linetex) + table.insert(texture, "^[makealpha:0,0,0") + return table.concat(texture, "") +end diff --git a/textures/airutils_name_canvas.png b/textures/airutils_name_canvas.png new file mode 100755 index 0000000000000000000000000000000000000000..65b13592f4a6c424fd1ebb419e887ea8863355cc GIT binary patch literal 5526 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 literal 0 HcmV?d00001