diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..9d05084 --- /dev/null +++ b/init.lua @@ -0,0 +1,341 @@ +-- painting - in-game painting for minetest-c55 + +-- THIS MOD CODE AND TEXTURES LICENSED +-- <3 TO YOU <3 +-- UNDER TERMS OF GPL LICENSE + +-- 2012 obneq aka jin xi + +-- a picture is drawn using a node(box) to draw the supporting canvas +-- and an entity which has the painting as its texture. +-- this texture is created by minetest-c55's internal image +-- compositing engine (see tile.cpp). + +--dofile(minetest.get_modpath("painting").."/crafting.lua") + +textures = { + white = "white.png", yellow = "yellow.png", + orange = "orange.png", red = "red.png", + violet = "violet.png", blue = "blue.png", + green= " green.png", magenta = "pink.png", + cyan = "cyan.png", lightgrey = "lightgrey.png", + darkgrey = "darkgrey.png", black = "black.png" +} + +res = 16 +thickness = 0.1 + +-- picture node +picbox = { + type = "fixed", + fixed = { -0.5, -0.5, 0.5, 0.5, 0.5, 0.5 - thickness } +} + +picnode = { + description = 'pic', + tiles = { "white.png" }, + inventory_image = "painted.png", + drawtype = "nodebox", + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = "facedir", + node_box = picbox, + selection_box = picbox, + groups = { snappy = 2, choppy = 2, oddly_breakable_by_hand = 2 }, + + --handle that right below, don't drop anything + drop = "", + + after_dig_node=function(pos, oldnode, oldmetadata, digger) + --find and remove the entity + local objects = minetest.env:get_objects_inside_radius(pos, 0.5) + for _, e in ipairs(objects) do + if e:get_luaentity().name == "painting:picent" then + e:remove() + end + end + + --put picture data back into inventory item + local data = oldmetadata.fields["painting:picturedata"] + local item = { name = "painting:paintedcanvas", count = 1, metadata = data } + digger:get_inventory():add_item("main", item) + end +} + +-- picture texture entity +picent = { + collisionbox = { 0,0,0,0,0,0 }, + visual = "upright_sprite", + textures = { "white.png" }, + + on_activate = function(self, staticdata) + local pos = self.object:getpos() + local meta = minetest.env:get_meta(pos) + local data = meta:get_string("painting:picturedata") + + if data then + self.object:set_properties({textures = { data }}) + end + end +} + +--paintedcanvas picture inventory item +paintedcanvas = { + inventory_image = "painted.png", + stack_max = 1, + + on_place = function(itemstack, placer, pointed_thing) + local data = itemstack:get_metadata() + local pos = pointed_thing.above + + --place node + local placerpos = placer:getpos() + local pos = pointed_thing.above + local dir = {x = pos.x - placerpos.x, y = pos.y - placerpos.y, z = pos.z - placerpos.z} + local fd = minetest.dir_to_facedir(dir) + + local pic = minetest.env:add_node(pos, { name = "painting:pic", + param2 = fd, + paramtype2 = 'none' }) + + local meta = minetest.env:get_meta(pos) + meta:set_string("painting:picturedata", data) + + --and entity + local dirs = {[0] = {x=0, z=1}, + [1] = {x=1, z=0}, + [2] = {x=0, z=-1}, + [3] = {x=-1, z=0}} + local dir=dirs[fd] + local off = 0.5-thickness-0.01 + + local np = { + x = pos.x+dir.x*off, + y = pos.y, + z = pos.z+dir.z*off} + + local p = minetest.env:add_entity(np, "painting:picent"):get_luaentity() + p.object:set_properties({textures = { data }}) + p.object:setyaw(math.pi*fd/-2) + + return ItemStack("") + end +} + +--canvas inventory item +canvas = { + inventory_image = "default_paper.png", + stack_max = 99, +} + +--canvas for drawing +canvasbox = { + type = "fixed", + fixed = { -0.5, -0.5, 0.0, 0.5, 0.5, thickness } +} + +canvasnode = { + description = 'canvas', + tiles = { "white.png" }, + inventory_image = "painted.png", + drawtype = "nodebox", + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = "facedir", + node_box = canvasbox, + selection_box = canvasbox, + groups = { snappy = 2, choppy = 2, oddly_breakable_by_hand = 2 }, + + drop = "", + + can_dig = function () + return true + end, + + on_construct = function(pos) + local node = minetest.env:get_node(pos) + local fd = node.param2 + + for y = 0, res-1 do + for x = 0, res-1 do + local xstep = x/res + local off = 1/(res*2) + + local boff = 0.01-off + + local dirs2 = { + [0] = { x =-0.5 + off + xstep, z = 0 - boff }, + [1] = { x = 0 - boff, z = 0.5 - off - xstep }, + [2] = { x = 0.5 - off - xstep, z = 0 + boff }, + [3] = { x = 0 + boff, z =-0.5 + off + xstep }, + } + + local dir = dirs2[fd] + + local np = {x = pos.x + dir.x, + y = pos.y + (0.5-1/(res*2)) - y/res, + z = pos.z + dir.z} + + local p = "painting:pixel_"..grid[x][y] + p = minetest.env:add_entity(np, pix):get_luaentity() + p.object:setyaw(math.pi*fd/-2) + p.pos={x=x, y=y} + p.name="easel" + end + end + end, + + after_dig_node=function(pos, oldnode, oldmetadata, digger) + --this is the imagestring that creates the texture + local data = "[combine:"..res.."x"..res..":" + for y=0,res-1 do + for x=0, res-1 do + data = data..x..","..y.."="..grid[x][y]..".png:" + end + end + + local easel = { x = pos.x, y = pos.y - 1, z = pos.z } + minetest.env:get_meta(easel):set_int("has_canvas", 0) + + local item = { name = "painting:paintedcanvas", count = 1, metadata = data } + digger:get_inventory():add_item("main", item) + + --clean up pixels + initgrid() + for _, e in pairs(minetest.luaentities) do + if e.name == "easel" then + e.object:remove() + end + end + end +} + +-- easel +easelbox = { + type="fixed", + fixed = { + --feet + {-0.4, -0.5, -0.5, -0.3, -0.4, 0.5 }, + { 0.3, -0.5, -0.5, 0.4, -0.4, 0.5 }, + --legs + {-0.4, -0.4, 0.1, -0.3, 1.5, 0.2 }, + { 0.3, -0.4, 0.1, 0.4, 1.5, 0.2 }, + --shelf + {-0.5, 0.35, -0.3, 0.5, 0.45, 0.1 } + } +} + +easel = { + description = 'easel', + tiles = { "default_wood.png" }, + drawtype = "nodebox", + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = "facedir", + node_box = easelbox, + selection_box = easelbox, + + groups = { snappy = 2, choppy = 2, oddly_breakable_by_hand = 2 }, + + on_punch = function(pos, node, player) + local wielded = player:get_wielded_item():get_name() + if wielded ~= 'painting:canvas' then + return + end + local meta = minetest.env:get_meta(pos) + local np = { x = pos.x, y = pos.y+1, z = pos.z } + + if minetest.env:get_node(np).name == "air" then + minetest.env:add_node(np, { name = "painting:canvasnode", + param2 = node["param2"], + paramtype2 = 'none' }) + end + + meta:set_int("has_canvas", 1) + local itemstack = ItemStack("painting:canvas") + player:get_inventory():remove_item("main", itemstack) + end, + + can_dig = function(pos,player) + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + + if meta:get_int("has_canvas") == 0 then + return true + end + return false + end +} + +--pixel and brushes +local c = 1/(res*2) +local p = "white.png" + +pixel = { + physical = true, + collisionbox = { -c, -c, -c, c, c, c }, + visual = "cube", + textures = { p, p, p, p, p, p }, + visual_size = { x = 1/res, y = 1/res }, + automatic_rotate = false, + + on_punch = function(self, hitter) + local name = hitter:get_wielded_item():get_name() + name = string.split(name, "_")[2] + + grid[self.pos.x][self.pos.y]=name + + local p = textures[name] + if p then + self.object:set_properties({textures = { p, p, p, p, p, p }}) + end + end +} + +brush = { + description = "brush", + inventory_image = "default_tool_steelaxe.png", + wield_image = "", + wield_scale = {x=1,y=1,z=1}, + stack_max = 99, + liquids_pointable = false, + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=0, + groupcaps={ + -- For example: + fleshy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1}, + snappy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1}, + choppy={times={[3]=0.90}, maxwear=0.05, maxlevel=0} + } + } +} + +minetest.register_entity("painting:picent", picent) +minetest.register_node("painting:pic", picnode) + +minetest.register_craftitem("painting:canvas", canvas) +minetest.register_craftitem("painting:paintedcanvas", paintedcanvas) +minetest.register_node("painting:canvasnode", canvasnode) + +minetest.register_node("painting:easel", easel) + +for color, texture in pairs(textures) do + minetest.register_entity("painting:pixel_"..color, pixel) + minetest.register_tool("painting:brush_"..color, brush) +end + +minetest.register_alias('easel', 'painting:easel') +minetest.register_alias('canvas', 'painting:canvas') + +function initgrid() + grid = {} + for x = 0, res-1 do + grid[x] = {} + for y = 0, res-1 do + grid[x][y] = "white" + end + end +end + +initgrid() diff --git a/textures/black.png b/textures/black.png new file mode 100644 index 0000000..daa5f56 Binary files /dev/null and b/textures/black.png differ diff --git a/textures/blue.png b/textures/blue.png new file mode 100644 index 0000000..1eb4217 Binary files /dev/null and b/textures/blue.png differ diff --git a/textures/cyan.png b/textures/cyan.png new file mode 100644 index 0000000..557ee60 Binary files /dev/null and b/textures/cyan.png differ diff --git a/textures/darkgrey.png b/textures/darkgrey.png new file mode 100644 index 0000000..d150307 Binary files /dev/null and b/textures/darkgrey.png differ diff --git a/textures/green.png b/textures/green.png new file mode 100644 index 0000000..1f965f9 Binary files /dev/null and b/textures/green.png differ diff --git a/textures/lightgrey.png b/textures/lightgrey.png new file mode 100644 index 0000000..30baffe Binary files /dev/null and b/textures/lightgrey.png differ diff --git a/textures/lime.png b/textures/lime.png new file mode 100644 index 0000000..9760cf6 Binary files /dev/null and b/textures/lime.png differ diff --git a/textures/orange.png b/textures/orange.png new file mode 100644 index 0000000..e951ba3 Binary files /dev/null and b/textures/orange.png differ diff --git a/textures/painted.png b/textures/painted.png new file mode 100644 index 0000000..c6eac7d Binary files /dev/null and b/textures/painted.png differ diff --git a/textures/pink.png b/textures/pink.png new file mode 100644 index 0000000..63a38b1 Binary files /dev/null and b/textures/pink.png differ diff --git a/textures/red.png b/textures/red.png new file mode 100644 index 0000000..26f57d2 Binary files /dev/null and b/textures/red.png differ diff --git a/textures/violet.png b/textures/violet.png new file mode 100644 index 0000000..18b8ccf Binary files /dev/null and b/textures/violet.png differ diff --git a/textures/white.png b/textures/white.png new file mode 100644 index 0000000..de406e1 Binary files /dev/null and b/textures/white.png differ diff --git a/textures/yellow.png b/textures/yellow.png new file mode 100644 index 0000000..140cb76 Binary files /dev/null and b/textures/yellow.png differ