Page 335 of 349

Re: Post your screenshots!

PostPosted: Sat Jan 26, 2019 22:17
by ShadMOrdre
Soon to be released.

Image
Image

Crafting without formspecs. Inspired by Sokomine's Anvil mod, itemshelf, gramophone and others.

Turned out MC story mode uses this style as well, but had no influence or motivation towards the making of this mod.

This code, hacked from zorman2000s itemshelf mod, belongs within a WIP mod of mine, but I'll post here, in hopes that somone with better code skills can clean it up some, or better yet, give me direction to do this myself. There are still some issues as well, mainly, itemstacks are not handled properly ATM, so use only one item in a stack at a time for now.

Code: Select all
-- Item shelf for generic objects
-- Inventory overlay and blast code taken from vessels mod in MTG
-- All other code by Zorman2000

local function get_shelf_formspec(inv_size)
   return "size[8,8]"..
      default.gui_bg..
      default.gui_bg_img..
      default.gui_slots..

      --"list[context;main;"..(math.abs((inv_size / 2) - 8) / 2)..",0.25;"..(inv_size / 2)..",2;]"..
      "list[context;input;"..(math.abs((inv_size / 2) - 8) / 2)..",0.25;3,3;]"..
      "list[current_player;main;0,3.75;8,1;]"..
      "list[current_player;main;0,5;8,3;8]"..
      "listring[context;main]"..
      "listring[current_player;main]"
end

local temp_texture
local temp_size

local temp_slot

local function get_obj_dir(param2)
   return ((param2 + 1) % 4)
end

local function update_shelf(pos)
   -- Remove all objects
   local objs = minetest.get_objects_inside_radius(pos, 0.875)
   for _,obj in pairs(objs) do
      obj:remove()
   end
   
   -- if not slot then
      -- slot = temp_slot
   -- end

   local node = minetest.get_node(pos)
   local node_dir = minetest.facedir_to_dir(((node.param2 + 2) % 4))
   --local node_dir = minetest.facedir_to_dir(((node.param2) % 4))
   --local node_dir = minetest.facedir_to_dir(((node.param2 + 2)))
   local obj_dir = minetest.facedir_to_dir(get_obj_dir(node.param2))
   local max_shown_items = minetest.get_item_group(node.name, "itemshelf_shown_items")

   -- Calculate initial position for entities
   -- local start_pos = {
   --    x=pos.x - (0.25 * obj_dir.x) - (node_dir.x * 0.25),
   --    y=pos.y + 0.25,
   --    z=pos.z - (0.25 * obj_dir.z) - (node_dir.z * 0.25)
   -- }
   --x = Left,Right;     y = Down/Up;     z = Front/Back;     (axis = neg/pos)
   -- How the below works: Following is a top view of a node
   --                              | +z (N) 0
   --                              |
   --                ------------------------
   --                |           |          |
   --                |           |          |
   --                |           |          |
   --     -x (W) 3     |           | (0,0)    |      +x (E) 1
   --     -------------|-----------+----------|--------------
   --                |           |          |
   --                |           |          |
   --                |           |          |
   --                |           |          |
   --                ------------------------
   --                             |
   --                         | -z (S) 2

   -- From the picture above, your front could be at either -z, -z, x or z.
   -- To get the entity closer to the front, you need to add a certain amount
   -- (e.g. 0.25) to the x and z coordinates, and then multiply these by the
   -- the node direction (which is a vector pointing outwards of the node face).
   -- Therefore, start_pos is:
   --local displacement = 0.715
   --local displacement = 0.555   
   local displacement = 0.555
   if max_shown_items == 6 then
      displacement = 0.555
   end
   local start_pos = {
      x=pos.x - (obj_dir.x * displacement) + (node_dir.x * 0.25),
      --y=pos.y + 0.2375,
      y=pos.y + 0.5625,
      z=pos.z - (obj_dir.z * displacement) + (node_dir.z * 0.25)
   }
   -- local start_pos = {
      -- x=pos.x - (obj_dir.x) + (node_dir.x * 0.25),
      -- y=pos.y + 0.5625,
      -- z=pos.z - (obj_dir.z) + (node_dir.z * 0.25)
   -- }

   -- Calculate amount of objects in the inventory
   local inv = minetest.get_meta(pos):get_inventory()
   local list = inv:get_list("input")
   local obj_count = 0
   for key,itemstack in pairs(list) do
      if not itemstack:is_empty() then
         obj_count = obj_count + 1
      end
   end
   minetest.log("Found "..dump(obj_count).." items on shelf inventory")
   if obj_count > 0 then
      local shown_items = math.min(#list, max_shown_items)
      for i = 1, shown_items do
         --local i = temp_slot
         local overhead = i
         if i > (shown_items / 3) then
            overhead = i - (shown_items / 3)
         end
         -- if i == ((shown_items / 2) + 1) then
            -- --start_pos.y = start_pos.y - 0.5125
            -- start_pos.z = start_pos.z + 0.2775
         -- end
         -- --local addition = 0.475
         local addition = 0.2775
         -- if shown_items == 6 then
            -- addition = 0.2775
         -- end
         if i == 1 then
            start_pos.x = pos.x - 0.3125
            start_pos.y = pos.y + 0.5625
            start_pos.z = pos.z + 0.3125
         end
         if i == 2 then
            start_pos.x = pos.x
            start_pos.y = pos.y + 0.5625
            start_pos.z = pos.z + 0.3125
         end
         if i == 3 then
            start_pos.x = pos.x + 0.3125
            start_pos.y = pos.y + 0.5625
            start_pos.z = pos.z + 0.3125
         end
         if i == 4 then
            -- start_pos.z = start_pos.z + 0.2775
            
            start_pos.x = pos.x - 0.3125
            start_pos.y = pos.y + 0.5625
            start_pos.z = pos.z
         end
         if i == 5 then
            start_pos.x = pos.x
            start_pos.y = pos.y + 0.5625
            start_pos.z = pos.z
         end
         if i == 6 then
            start_pos.x = pos.x + 0.3125
            start_pos.y = pos.y + 0.5625
            start_pos.z = pos.z
         end
         if i == 7 then
            -- --start_pos.x = start_pos.x - (obj_dir.x * displacement) + (node_dir.x * 0.25)
            -- start_pos.x = start_pos.x - (obj_dir.x * displacement) - ((obj_dir.x * displacement) / 2)
            -- start_pos.z = start_pos.z + 0.2775
            
            start_pos.x = pos.x - 0.3125
            start_pos.y = pos.y + 0.5625
            start_pos.z = pos.z - 0.3125
         end
         if i == 8 then
            start_pos.x = pos.x
            start_pos.y = pos.y + 0.5625
            start_pos.z = pos.z - 0.3125
         end
         if i == 9 then
            start_pos.x = pos.x + 0.3125
            start_pos.y = pos.y + 0.5625
            start_pos.z = pos.z - 0.3125
         end
         -- local obj_pos = {
            -- x=start_pos.x + (addition * overhead * obj_dir.x), --- (node_dir.z * overhead * 0.25),
            -- y=start_pos.y,
            -- z=start_pos.z + (addition * overhead * obj_dir.z) --- (node_dir.x * overhead * 0.25),
         -- }
         local obj_pos = {
            x=start_pos.x,
            y=start_pos.y,
            z=start_pos.z,
         }

         if not list[i]:is_empty() then
            minetest.log("Adding item entity at "..minetest.pos_to_string(obj_pos))
            temp_texture = list[i]:get_name()
            temp_size = 0.8/max_shown_items
            minetest.log("Size: "..dump(temp_size))
            local ent = minetest.add_entity(obj_pos, "lib_tools:draft_table_item")
            ent:set_properties({
               wield_item = temp_texture,
               visual_size = {x = 0.8/max_shown_items, y = 0.8/max_shown_items}
            })
         end
      end
   end

end

draft_table = {}

-- Definable properties:
--   - description
--   - textures (if drawtype is nodebox)
--   - nodebox (like default minetest.register_node def)
--   - mesh (like default minetest.register_node def)
--   - item capacity (how many items will fit into the shelf, use even numbers, max 16)
--   - shown_items (how many items to show, will always show first (shown_items/2) items of each row, max 6)
function lib_tools.register_shelf(name, def)
   local drawtype = "nodebox"
   if def.mesh then
      drawtype = "mesh"
   end
   minetest.register_node("lib_tools:"..name, {
      description = def.description,
      tiles = def.textures,
      paramtype = "light",
      paramtype2 = "facedir",
      drawtype = drawtype,
      node_box = def.nodebox,
      mesh = def.mesh,
      groups = {cracky = 2, itemshelves = 1, itemshelf_shown_items = def.shown_items or 4},
      
      on_construct = function(pos)
         -- Initialize inventory
         local meta = minetest.get_meta(pos)
         local inv = meta:get_inventory()
          inv:set_size("input", def.capacity or 4)
          -- Initialize formspec
          --meta:set_string("formspec", get_shelf_formspec(def.capacity or 4))
      end,

      after_place_node = function(pos, placer)
         local meta = minetest.get_meta(pos)
         meta:set_string("owner", placer:get_player_name() or "")
      end,

      on_metadata_inventory_put = update_shelf,
      on_metadata_inventory_take = update_shelf,
      
      allow_metadata_inventory_put = function(pos, listname, index, stack, player)
         local meta = minetest.get_meta(pos)
         if listname~="input" then
            return 0
         end
         --    if minetest.get_item_group(stack:get_name(), "music_disc") ~= 0 then
         --       return stack:get_count()
         --    end
         --    return 0
         if meta:get_inventory():room_for_item("input", stack) then
            return stack:get_count()
         end
         return 0
      end,

      allow_metadata_inventory_take = function(pos, listname, index, stack, player)
         if listname~="input" then
            return 0
         end
         return stack:get_count()
      end,
      
      can_dig = function(pos,player)
         local meta  = minetest.get_meta(pos)
         local inv   = meta:get_inventory()
      
         if not inv:is_empty("input") then
            return false
         end
         return true
      end,

      on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
      
         local inv_index = 0
      
         local user_name=clicker:get_player_name()
         local normal,p = place_rotated.get_point(pointed_thing.above,pointed_thing.under,clicker)

         
         if p then
            minetest.chat_send_player(user_name,"Position within node:")
            minetest.chat_send_player(user_name,"X: "..p.x)
            minetest.chat_send_player(user_name,"Y: "..p.y)
            minetest.chat_send_player(user_name,"Z: "..p.z)
            
            if ((p.x >= -0.4375 and p.z >= 0.1875) and (p.x <= -0.1875 and p.z <= 0.4375)) then
            
               inv_index = 1
               minetest.chat_send_player(user_name,"inv_index: "..tostring(inv_index))
               
            elseif ((p.x >= -0.125 and p.z >= 0.1875) and (p.x <= 0.125 and p.z <= 0.4375)) then
            
               inv_index = 2
               minetest.chat_send_player(user_name,"inv_index: "..tostring(inv_index))
               
            elseif ((p.x >= 0.1875 and p.z >= 0.1875) and (p.x <= 0.4375 and p.z <= 0.4375)) then
            
               inv_index = 3
               minetest.chat_send_player(user_name,"inv_index: "..tostring(inv_index))
               
            elseif ((p.x >= -0.4375 and p.z >= -0.125) and (p.x <= -0.1875 and p.z <= 0.125)) then
            
               inv_index = 4
               minetest.chat_send_player(user_name,"inv_index: "..tostring(inv_index))
               
            elseif ((p.x >= -0.125 and p.z >= -0.125) and (p.x <= 0.125 and p.z <= 0.125)) then
            
               inv_index = 5
               minetest.chat_send_player(user_name,"inv_index: "..tostring(inv_index))
               
            elseif ((p.x >= 0.1875 and p.z >= -0.125) and (p.x <= 0.4375 and p.z <= 0.125)) then
            
               inv_index = 6
               minetest.chat_send_player(user_name,"inv_index: "..tostring(inv_index))
               
            elseif ((p.x >= -0.4375 and p.z >= -0.4375) and (p.x <= -0.1875 and p.z <= -0.1875)) then
            
               inv_index = 7
               minetest.chat_send_player(user_name,"inv_index: "..tostring(inv_index))
               
            elseif ((p.x >= -0.125 and p.z >= -0.4375) and (p.x <= 0.125 and p.z <= -0.1875)) then
            
               inv_index = 8
               minetest.chat_send_player(user_name,"inv_index: "..tostring(inv_index))
               
            elseif ((p.x >= 0.1875 and p.z >= -0.4375) and (p.x <= 0.4375 and p.z <= -0.1875)) then
            
               inv_index = 9
               minetest.chat_send_player(user_name,"inv_index: "..tostring(inv_index))
               
            end
         else
            minetest.chat_send_player(user_name,"Could not get point")
         end

         temp_slot = inv_index
         local meta = minetest.get_meta(pos)
         local inv = meta:get_inventory()

         if inv_index ~= 0 then
            if itemstack:get_count() == 0 then
               if not inv:is_empty("input") then
                  local return_stack = inv:get_stack("input", inv_index)
                  inv:set_stack("input", inv_index, nil)
                  local wield_index = clicker:get_wield_index()
                  clicker:get_inventory():set_stack("main", wield_index, return_stack)
                  --remove_item(pos, node)
                  update_shelf(pos)
                  return return_stack
               end      
            end
            local this_def = minetest.registered_nodes[node.name]
            if this_def.allow_metadata_inventory_put(pos, "input", inv_index, itemstack:peek_item(), clicker) > 0 then
               local return_stack = inv:get_stack("input", inv_index)
               
               local p_ctrl = clicker:get_player_control()
               local s
               if p_ctrl.sneak then
                  s = itemstack:take_item()
               else
                  s = itemstack:take_item(1)
               end
               --inv:add_item("input", s)
               inv:set_stack("input", inv_index, s)
               --update_item(pos,node)
               update_shelf(pos)
               return return_stack
            end
         else
            if not inv:is_empty("input") then
               local craft_recipe = {
                  method = "normal",
                  width = 3,
                  items = {
                     inv:get_stack("input", 1),
                     inv:get_stack("input", 2),
                     inv:get_stack("input", 3),
                     inv:get_stack("input", 4),
                     inv:get_stack("input", 5),
                     inv:get_stack("input", 6),
                     inv:get_stack("input", 7),
                     inv:get_stack("input", 8),
                     inv:get_stack("input", 9)
                  }
               }

               local craft_out, dec_inp = minetest.get_craft_result(craft_recipe)
               
               if craft_out.item:get_name() ~= "" then
                  minetest.chat_send_player(user_name, "craft_out.item:  " .. craft_out.item:get_name())
                  local t_pos = {
                     x = pos.x,
                     y = pos.y + 0.5625,
                     z = pos.z
                  }
                  inv:set_stack("input", 1, nil)
                  inv:set_stack("input", 2, nil)
                  inv:set_stack("input", 3, nil)
                  inv:set_stack("input", 4, nil)
                  inv:set_stack("input", 5, nil)
                  inv:set_stack("input", 6, nil)
                  inv:set_stack("input", 7, nil)
                  inv:set_stack("input", 8, nil)
                  inv:set_stack("input", 9, nil)
                  update_shelf(pos)
                  minetest.add_item(t_pos, craft_out.item:take_item())
                  -- local co = craft_out.item:take_item()
                  -- return co
                  return
               else
                  return itemstack
               end
            else
               return itemstack
            end
         end
      end,

      on_punch = function(pos, node, puncher)
         if( not( pos ) or not( node ) or not( puncher )) then
            return
         end

         local wielded = puncher:get_wielded_item()
         local meta = minetest.get_meta(pos)
         local inv  = meta:get_inventory()
         
         if wielded:get_count() == 0 then
            if not inv:is_empty("input") then
               local return_stack = inv:get_stack("input", 1)
               inv:set_stack("input", 1, nil)
               local wield_index = puncher:get_wield_index()
               puncher:get_inventory():set_stack("main", wield_index, return_stack)
               --remove_item(pos, node)
               update_shelf(pos)
            end      
         end
         
         -- -- only punching with the hammer is supposed to work
         -- if wielded:get_name() ~= 'lib_tools:anvil_hammer' then
            -- return
         -- end
         
         local input = inv:get_stack('input',1)
      
         -- -- only tools can be repaired
         -- if( not( input )
         -- or input:is_empty()
               -- or input:get_name() == "technic:water_can"
               -- or input:get_name() == "technic:lava_can" ) then
            -- return
         -- end
      
         -- -- 65535 is max damage
         -- local damage_state = 40-math.floor(input:get_wear()/1638)
      
         -- local tool_name = input:get_name()

         -- local hud2 = nil
         -- local hud3 = nil
         -- if( input:get_wear()>0 ) then
            -- hud2 = puncher:hud_add({
               -- hud_elem_type = "statbar",
               -- text = "default_cloud.png^[colorize:#ff0000:256",
               -- number = 40,
               -- direction = 0, -- left to right
               -- position = {x=0.5, y=0.65},
               -- alignment = {x = 0, y = 0},
               -- offset = {x = -320, y = 0},
               -- size = {x=32, y=32},
            -- })
            -- hud3 = puncher:hud_add({
               -- hud_elem_type = "statbar",
               -- text = "default_cloud.png^[colorize:#00ff00:256",
               -- number = damage_state,
               -- direction = 0, -- left to right
               -- position = {x=0.5, y=0.65},
               -- alignment = {x = 0, y = 0},
               -- offset = {x = -320, y = 0},
               -- size = {x=32, y=32},
            -- })
         -- end
         -- minetest.after(2, function()
            -- if( puncher ) then
               -- puncher:hud_remove(hud2)
               -- puncher:hud_remove(hud3)
            -- end
         -- end)
      
         -- -- tell the player when the job is done
         -- if(   input:get_wear() == 0 ) then
            -- local tool_desc
            -- if minetest.registered_items[tool_name] and minetest.registered_items[tool_name].description then
               -- tool_desc = minetest.registered_items[tool_name].description
            -- else
               -- tool_desc = tool_name
            -- end
            -- minetest.chat_send_player( puncher:get_player_name(), S('Your @1 has been repaired successfully.', tool_desc))
            -- return
         -- else
            -- --pos.y = pos.y + anvil_item_displacement
            -- pos.y = pos.y + 7/16
            -- minetest.sound_play({name="anvil_clang"}, {pos=pos})
            -- minetest.add_particlespawner({
               -- amount = 10,
               -- time = 0.1,
               -- minpos = pos,
               -- maxpos = pos,
               -- minvel = {x=2, y=3, z=2},
               -- maxvel = {x=-2, y=1, z=-2},
               -- minacc = {x=0, y= -10, z=0},
               -- maxacc = {x=0, y= -10, z=0},
               -- minexptime = 0.5,
               -- maxexptime = 1,
               -- minsize = 1,
               -- maxsize = 1,
               -- collisiondetection = true,
               -- vertical = false,
               -- texture = "anvil_spark.png",
            -- })
         -- end
      
         -- -- do the actual repair
         -- input:add_wear( -5000 ) -- equals to what technic toolshop does in 5 seconds
         -- inv:set_stack("input", 1, input)
      
         -- -- damage the hammer slightly
         -- wielded:add_wear( 100 )
         -- puncher:set_wielded_item( wielded )
      end,

      on_dig = function(pos, node, digger)
         -- Clear any object disc
         local objs = minetest.get_objects_inside_radius(pos, 0.7)
         for _,obj in pairs(objs) do
            obj:remove()
         end
         -- Pop-up disc if existing
         local meta = minetest.get_meta(pos)
         local list = meta:get_inventory():get_list("input")
         if list then
            for _,item in pairs(list) do
               local drop_pos = {
                  x=math.random(pos.x - 0.5, pos.x + 0.5),
                  y=pos.y,
                  z=math.random(pos.z - 0.5, pos.z + 0.5)}
               minetest.add_item(pos, item:get_name())
            end
         end
         -- Remove node
         minetest.remove_node(pos)
      end,
      
      on_blast = function(pos)
         local drops = {}
         default.get_inventory_drops(pos, "lib_tools:draft_table", drops)
         drops[#drops + 1] = "lib_tools:draft_table"
         minetest.remove_node(pos)
         return drops
      end
   })
end

-- Entity for shelf
minetest.register_entity("lib_tools:draft_table_item", {
   hp_max = 1,
   visual = "wielditem",
   visual_size = {x = 0.20, y = 0.20},
   collisionbox = {0,0,0, 0,0,0},
   physical = false,
   on_activate = function(self, staticdata)
      -- Staticdata
      local data = {}
      if staticdata ~= nil and staticdata ~= "" then
         local cols = string.split(staticdata, "|")
         data["itemstring"] = cols[1]
         data["visualsize"] = tonumber(cols[2])
      end

      -- Texture
      if temp_texture ~= nil then
         -- Set texture from temp
         self.itemstring = temp_texture
         temp_texture = nil
      elseif staticdata ~= nil and staticdata ~= "" then
         -- Set texture from static data
         self.itemstring = data.itemstring
      end
      -- Set texture if available
      if self.itemstring ~= nil then
         self.wield_item = self.itemstring
      end
      
      -- Visual size
      if temp_size ~= nil then
         self.visualsize = temp_size
         temp_size = nil
      elseif staticdata ~= nil and staticdata ~= "" then
         self.visualsize = data.visualsize
      end
      -- Set visual size if available
      if self.visualsize ~= nil then
         self.visual_size = {x=self.visualsize, y=self.visualsize}
      end

      -- Set object properties
      self.object:set_properties(self)
      
   end,
   get_staticdata = function(self)
      local result = ""
      if self.itemstring ~= nil then
         result = self.itemstring.."|"
      end
      if self.visualsize ~= nil then
         result = result..self.visualsize
      end
      return result
   end,
})

local default_table = {
   type = "fixed",
   fixed = {
      {-0.5, 0.375, -0.5, 0.5, 0.5, 0.5}, -- NodeBox1
      {-0.375, -0.5, -0.375, -0.25, 0.375, -0.25}, -- NodeBox3
      {0.25, -0.5, -0.375, 0.375, 0.375, -0.25}, -- NodeBox5
      {-0.375, -0.5, 0.25, -0.25, 0.375, 0.375}, -- NodeBox6
      {0.25, -0.5, 0.25, 0.375, 0.375, 0.375}, -- NodeBox7
      {-0.3125, -0.125, -0.3125, 0.3125, -0.0625, 0.3125}, -- NodeBox8
   }
}



lib_tools.register_shelf("draft_table", {
   description = "Drafting Table (For crafting)",
   textures = {
      "lib_tools_draft_table_top.png",
      "worktable_side.png",
      "worktable_side.png",
      "worktable_side.png",
      "worktable_side.png",
      "worktable_front.png",
   },
   nodebox = default_table,
   capacity = 9,
   shown_items = 9
})




Shad

My Vacations in Ethereal Valleys

PostPosted: Sun Jan 27, 2019 00:06
by PEAK
… just a photo album

+ Spoiler

Re: Post your screenshots!

PostPosted: Sun Jan 27, 2019 01:37
by Sokomine
PEAK wrote:Little village

Where does the railtrack start that leads to that village? It seems to be a great place for a relaxed holliday.

Re: Post your screenshots!

PostPosted: Sun Jan 27, 2019 18:05
by IcyDiamond
This one looks like a naturally generated wizard's tower.
Image

Re: Post your screenshots!

PostPosted: Mon Jan 28, 2019 03:42
by PEAK
Sokomine wrote:Where does the railtrack start that leads to that village?

Who knows…
Image
Sokomine wrote:It seems to be a great place for a relaxed holliday.

I tried to create atmosphere by letting only little space between the houses.

Re: Post your screenshots!

PostPosted: Mon Jan 28, 2019 06:44
by Superuser
A realm I found around -20000 on Blocky Survival.
Image

Re: Post your screenshots!

PostPosted: Mon Jan 28, 2019 23:46
by Superuser
sorcerykid wrote:Profiles allow users to build a personalized homepage, to describe themselves, their interests, etc. with access to the complete Bedrock Markup Language (currently used in the signs_rx mod) -- which has been extended to with support for embedded images, hyperlinks, and dynamic variables.

that's something that I would be excited to see

Re: Post your screenshots!

PostPosted: Tue Jan 29, 2019 10:23
by Hume2
I was experimenting with mapgen again. I was on a large plain and then I found a big hole. And then I found another one next to it. And then I didn't find any other.
PS: It's modified v7.
Image
Image

Re: Post your screenshots!

PostPosted: Wed Jan 30, 2019 13:58
by voxelproof
For those who suffer from harsh winter conditions:

Image

Of course such summer idyll is possible only in Heaven. Or Minetest.

Re: Post your screenshots!

PostPosted: Wed Jan 30, 2019 14:48
by sorcerykid
Toying around with my new image rendering library for Minetest :) To my knowledge this is the first attempt to dynamically generate bitmap and raster images in formspecs (without having to restart the server and preload textures at login). This workaround takes advantage of a unique "feature" of formspec text labels -- without relying on hundreds of box or image elements.

Currently, it is possible to import PPM images from disk as well as to draw primitive vector graphics (circle, line, etc.) into a newly initialized image. There are three rasterizer modes available, which support 1-bit and 2-bit grayscale images. True-color images are down-converted automatically, with optional depth and gamma parameters. I'm still working on adding support for RGB color output.

Imagen Graphic Rasterizer:
Image

Orignial PNG Image:
Image

Imagen Picture Rasterizer:
Image

Original PNG Image:
Image

Imagen Artwork Rasterizer:
Image

There is a slight interlacing effect with the "artwork" (line art) rasterizer, due to the fact Minetest renders text with shadows. I haven't found a suitable fix. However, these artifacts can be overcome somewhat by using the "picture" (photo) rasterizer instead. However graphical text will be slightly blurrier in this mode (although I'm still tweaking the parameters).

Altogether, the renderer is decently fast, clocking in at about 13 ms for a 500 x 250 bitmap. My main impetus for creating Imagen is so that players can share screenshots and drawings directly in game and eventually between different servers.

Re: Post your screenshots!

PostPosted: Wed Jan 30, 2019 22:03
by texmex
That is awesome, sorcerykid.

Re: Post your screenshots!

PostPosted: Fri Feb 01, 2019 18:27
by Hybrid Dog
How can you make all the small pixels by only using text?

Re: Post your screenshots!

PostPosted: Fri Feb 01, 2019 20:42
by Sokomine
Hostile mobs of the NNSM (not so simple mobs) on the Not so simple server work pretty well, even when attacking in large masses:
Image

There are many decorative structures that spawn at mapgen time and which contai mob spawners. Those of manticores and blocos are particulary nice. This is the home of the famous ice boss. Even such large structures spawn pretty well most of the time:
Image

Manticores in love:
Image

Termos' texture experiment

PostPosted: Fri Feb 01, 2019 21:28
by Wuzzy
Image

Re: Termos' texture experiment

PostPosted: Fri Feb 01, 2019 22:12
by Lone_Wolf
Wuzzy wrote:Image

That looks a lot better. Assuming the darker grass there has yet to be changed...

Re: Post your screenshots!

PostPosted: Fri Feb 01, 2019 23:14
by voxelproof
Sokomine wrote:Manticores in love:


Rather mantes. Looks as if one of them will be soon devoured.

_____________________________________________________________

Playing around with that strange mod:

Image
Ultimate Peacemaker

Schematics will be uploaded as soon as I've completed the mod.

Re: Post your screenshots!

PostPosted: Sat Feb 02, 2019 02:28
by sorcerykid
I just finished work on a brand new trophy mod, at the request of a player on JT2 that is soon to be holding a PvP tournament. I borrowed the model from VenessaE's HomeDecor modpack, then added about 200 lines of code to make trophies truly come to life :D

Image

Image

Image

The inscription information is retained in the node meta and the item meta. So once it is set by the presenter, then the trophy can placed, dug, dropped, and even stored in a chest, and it will always be associated with the winner.

Re: Post your screenshots!

PostPosted: Sat Feb 02, 2019 03:31
by Lone_Wolf
sorcerykid wrote:
+ Post

Nice
Maybe add support for 1st, 2nd, and 3rd places?

Re: Post your screenshots!

PostPosted: Sat Feb 02, 2019 08:06
by Chibi ghost
nice idea

Re: Post your screenshots!

PostPosted: Sun Feb 03, 2019 05:30
by Lone_Wolf
Minetest 5.0 Carpathian (Something sticking down the top middle. I need to take screenshots properly)
Image

Re: Post your screenshots!

PostPosted: Sun Feb 03, 2019 10:02
by Chibi ghost
looks dramatic :D

Re: Post your screenshots!

PostPosted: Sun Feb 03, 2019 10:58
by voxelproof
Lone_Wolf wrote:Minetest 5.0 Carpathian (Something sticking down the top middle. I need to take screenshots properly)


Screenshot is very good. Btw interesting map generation seems to lurk behind this scene. On my laptop taking a decent shot requires usually doing a lot of flying to erase all gaps in terrain generation, so, well, even in games with apparently simple graphics obtaining desired results also needs some time.
_______________________________________________________________________________________

A little more ambitious attempt in 'voxel' art: re-creating "The Great Wave off Kanagawa" by Hokusai.
Despite I've chosen a simplified version of this world-famous print, cubic grid with proper node palette seems to add a lot of expression to the picture:

Image

The schematics will be uploaded in its horizontal version (as depicted above) -- the lighting reveals all colours properly, otherwise when it's put vertically the framing of the voxel picture casts a shadow, changing the look. It's of course up to the future users how they'd prefer to have this art displayed, its darker (horizontal) version seems to be somewhat yet more eerie:

Image

This creation as well as the former one ("Peace") has been made using Real Terrain by bobomb and my own custom palette mod.

Of course I'm aware that, technically speaking, this is not a 'true' voxel art; voxels, like pixels, have no textures and can represent only one colour. It should be probably better called a "cubic art" or "block art", something like that.

Re: Post your screenshots!

PostPosted: Sun Feb 03, 2019 11:41
by Chibi ghost
it's a very cool example of what two mods combined can do

Re: Post your screenshots!

PostPosted: Mon Feb 04, 2019 09:19
by voxelproof
Chibi ghost wrote:it's a very cool example of what two mods combined can do


Another shot (slightly brightened and sharpened):

Image

Actually the hippie-psychedelic palette I used in both schematics is great for pop-art creations (and making voxel ads perhaps ;) ). However it's also possible to undertake more serious effort to reflect deeper layers of artistic expression. I've noticed that it's possible to re-create old masterpieces of painting giving them an even more convincing charge of aesthetic value, and revealing new dimension of well known artworks. It's strange, but, perhaps, sometimes it can be even better than the original as far as a viewer's experience is concerned.

This is re-creation of Bruegel's "Tower of Babel" made with Real Terrain and my Tapestry palette mod. The picture needs only 14 custom textures to achieve very interesting effect:

Image

Closeup of the canvas:

Image

Re: Post your screenshots!

PostPosted: Mon Feb 04, 2019 11:49
by Wuzzy
Image