mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-26 04:21:07 +01:00
Add paintings
This commit is contained in:
parent
d1d7c026e1
commit
bfd2f0ebc7
7 changed files with 336 additions and 0 deletions
276
mods/ENTITIES/mcl_paintings/init.lua
Normal file
276
mods/ENTITIES/mcl_paintings/init.lua
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
mcl_paintings = {}
|
||||||
|
|
||||||
|
dofile(minetest.get_modpath(minetest.get_current_modname()).."/paintings.lua")
|
||||||
|
|
||||||
|
local S = minetest.get_translator("mcl_paintings")
|
||||||
|
|
||||||
|
local wood = "[combine:16x16:-192,0=mcl_paintings_paintings.png"
|
||||||
|
|
||||||
|
-- Check if there's a painting for provided painting size.
|
||||||
|
-- If yes, returns the arguments.
|
||||||
|
-- If not, returns the next smaller available painting.
|
||||||
|
local shrink_painting = function(x, y)
|
||||||
|
if x > 4 or y > 4 then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local xstart = x
|
||||||
|
local painting
|
||||||
|
while not painting do
|
||||||
|
painting = mcl_paintings.paintings[y] and mcl_paintings.paintings[y][x]
|
||||||
|
if type(painting) == "table" then
|
||||||
|
break
|
||||||
|
elseif type(painting) == "number" then
|
||||||
|
x = painting
|
||||||
|
painting = nil
|
||||||
|
else
|
||||||
|
x = xstart
|
||||||
|
y = y - 1
|
||||||
|
end
|
||||||
|
if y < 1 then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if type(painting) == "table" then
|
||||||
|
return x, y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local get_painting = function(x, y, motive)
|
||||||
|
local painting = mcl_paintings.paintings[y] and mcl_paintings.paintings[y][x] and mcl_paintings.paintings[y][x][motive]
|
||||||
|
if not painting then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local px, py = -painting.cx, -painting.cy
|
||||||
|
local sx, sy = 16*x, 16*y
|
||||||
|
return "[combine:"..sx.."x"..sy..":"..px..","..py.."=mcl_paintings_paintings.png"
|
||||||
|
end
|
||||||
|
|
||||||
|
local get_random_painting = function(x, y)
|
||||||
|
if not mcl_paintings.paintings[y] or not mcl_paintings.paintings[y][x] then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local max = #mcl_paintings.paintings[y][x]
|
||||||
|
if max < 1 then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local r = math.random(1, max)
|
||||||
|
return get_painting(x, y, r), r
|
||||||
|
end
|
||||||
|
|
||||||
|
local size_to_minmax = function(size)
|
||||||
|
local min, max
|
||||||
|
if size == 2 then
|
||||||
|
min = -0.5
|
||||||
|
max = 1.5
|
||||||
|
elseif size == 3 then
|
||||||
|
min = -1.5
|
||||||
|
max = 1.5
|
||||||
|
elseif size == 4 then
|
||||||
|
min = -1.5
|
||||||
|
max = 2.5
|
||||||
|
else
|
||||||
|
min = -0.5
|
||||||
|
max = 0.5
|
||||||
|
end
|
||||||
|
return min, max
|
||||||
|
end
|
||||||
|
|
||||||
|
local size_to_minmax_entity = function(size)
|
||||||
|
return -size/2, size/2
|
||||||
|
end
|
||||||
|
|
||||||
|
local set_entity = function(object)
|
||||||
|
local ent = object:get_luaentity()
|
||||||
|
local wallm = ent._facing
|
||||||
|
local xsize = ent._xsize
|
||||||
|
local ysize = ent._ysize
|
||||||
|
local exmin, exmax = size_to_minmax_entity(xsize)
|
||||||
|
local eymin, eymax = size_to_minmax_entity(ysize)
|
||||||
|
local visual_size = { x=xsize-0.0001, y=ysize-0.0001, z=1/32 }
|
||||||
|
if not ent._xsize or not ent._ysize or not ent._motive then
|
||||||
|
minetest.log("error", "[mcl_paintings] Painting loaded with missing painting values!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local painting = get_painting(xsize, ysize, ent._motive)
|
||||||
|
if not painting then
|
||||||
|
minetest.log("error", "[mcl_paintings] No painting found for size "
|
||||||
|
..xsize..","..ysize..", motive number "..ent._motive.."!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if wallm == 4 or wallm == 5 then
|
||||||
|
object:set_properties({
|
||||||
|
selectionbox = { exmin, eymin, -1/64, exmax, eymax, 1/64 },
|
||||||
|
visual_size = visual_size,
|
||||||
|
textures = { wood, wood, wood, wood, painting, wood },
|
||||||
|
})
|
||||||
|
else
|
||||||
|
object:set_properties({
|
||||||
|
selectionbox = { -1/64, eymin, exmin, 1/64, eymax, exmax },
|
||||||
|
visual_size = visual_size,
|
||||||
|
textures = { wood, wood, wood, wood, painting, wood },
|
||||||
|
})
|
||||||
|
end
|
||||||
|
local dir = minetest.wallmounted_to_dir(wallm)
|
||||||
|
if not dir then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
object:set_yaw(minetest.dir_to_yaw(dir))
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_entity("mcl_paintings:painting", {
|
||||||
|
visual = "cube",
|
||||||
|
visual_size = { x=0.999, y=0.999, z=1/32 },
|
||||||
|
selectionbox = { -1/64, -0.5, -0.5, 1/64, 0.5, 0.5 },
|
||||||
|
physical = false,
|
||||||
|
collide_with_objects = false,
|
||||||
|
textures = { wood, wood, wood, wood, wood, wood },
|
||||||
|
hp_max = 1,
|
||||||
|
|
||||||
|
_motive = 0,
|
||||||
|
_pos = nil,
|
||||||
|
_facing = 2,
|
||||||
|
_xsize = 1,
|
||||||
|
_ysize = 1,
|
||||||
|
on_activate = function(self, staticdata)
|
||||||
|
if staticdata and staticdata ~= "" then
|
||||||
|
local data = minetest.deserialize(staticdata)
|
||||||
|
if data then
|
||||||
|
self._facing = data._facing
|
||||||
|
self._pos = data._pos
|
||||||
|
self._motive = data._motive
|
||||||
|
self._xsize = data._xsize
|
||||||
|
self._ysize = data._ysize
|
||||||
|
end
|
||||||
|
end
|
||||||
|
set_entity(self.object)
|
||||||
|
end,
|
||||||
|
get_staticdata = function(self)
|
||||||
|
local data = {
|
||||||
|
_facing = self._facing,
|
||||||
|
_pos = self._pos,
|
||||||
|
_motive = self._motive,
|
||||||
|
_xsize = self._xsize,
|
||||||
|
_ysize = self._ysize,
|
||||||
|
}
|
||||||
|
return minetest.serialize(data)
|
||||||
|
end,
|
||||||
|
on_death = function(self, killer)
|
||||||
|
-- Drop as item on death
|
||||||
|
if not minetest.settings:get_bool("creative_mode") then
|
||||||
|
local pos = self._pos
|
||||||
|
if not pos then
|
||||||
|
pos = self.object:get_pos()
|
||||||
|
end
|
||||||
|
minetest.add_item(pos, "mcl_paintings:painting")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craftitem("mcl_paintings:painting", {
|
||||||
|
description = S("Painting"),
|
||||||
|
inventory_image = "mcl_paintings_painting.png",
|
||||||
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
|
if pointed_thing.type ~= "node" then
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
local dir = vector.subtract(pointed_thing.above, pointed_thing.under)
|
||||||
|
dir = vector.normalize(dir)
|
||||||
|
if dir.y ~= 0 then
|
||||||
|
-- Ceiling/floor paintings are not supported
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
local wallm = minetest.dir_to_wallmounted(dir)
|
||||||
|
if wallm then
|
||||||
|
local ppos = pointed_thing.above
|
||||||
|
local xmax
|
||||||
|
local ymax = 4
|
||||||
|
local xmaxes = {}
|
||||||
|
local ymaxed = false
|
||||||
|
local negative = dir.x < 0 or dir.z > 0
|
||||||
|
-- Check maximum possible painting size
|
||||||
|
local t
|
||||||
|
for y=0,3 do
|
||||||
|
for x=0,3 do
|
||||||
|
local k = x
|
||||||
|
if negative then
|
||||||
|
k = -k
|
||||||
|
end
|
||||||
|
if dir.z ~= 0 then
|
||||||
|
t = {x=k,y=y,z=0}
|
||||||
|
else
|
||||||
|
t = {x=0,y=y,z=k}
|
||||||
|
end
|
||||||
|
local unode = minetest.get_node(vector.add(pointed_thing.under, t))
|
||||||
|
local anode = minetest.get_node(vector.add(ppos, t))
|
||||||
|
local udef = minetest.registered_nodes[unode.name]
|
||||||
|
local adef = minetest.registered_nodes[anode.name]
|
||||||
|
if (not (udef and udef.walkable)) or (not adef or adef.walkable) then
|
||||||
|
xmaxes[y+1] = x
|
||||||
|
if x == 0 and not ymaxed then
|
||||||
|
ymax = y
|
||||||
|
ymaxed = true
|
||||||
|
end
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not xmaxes[y] then
|
||||||
|
xmaxes[y] = 4
|
||||||
|
end
|
||||||
|
end
|
||||||
|
xmax = math.max(unpack(xmaxes))
|
||||||
|
|
||||||
|
local xsize, ysize = xmax, ymax
|
||||||
|
xsize, ysize = shrink_painting(xsize, ysize)
|
||||||
|
if not xsize then
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
local _, exmax = size_to_minmax_entity(xsize)
|
||||||
|
local _, eymax = size_to_minmax_entity(ysize)
|
||||||
|
local pposa = vector.subtract(ppos, vector.multiply(dir, 0.5-2/64))
|
||||||
|
local pexmax
|
||||||
|
local peymax = eymax - 0.5
|
||||||
|
if negative then
|
||||||
|
pexmax = -exmax + 0.5
|
||||||
|
else
|
||||||
|
pexmax = exmax - 0.5
|
||||||
|
end
|
||||||
|
if dir.z ~= 0 then
|
||||||
|
pposa = vector.add(pposa, {x=pexmax, y=peymax, z=0})
|
||||||
|
else
|
||||||
|
pposa = vector.add(pposa, {x=0, y=peymax, z=pexmax})
|
||||||
|
end
|
||||||
|
local painting, pid = get_random_painting(xsize, ysize)
|
||||||
|
if not painting then
|
||||||
|
minetest.log("error", "[mcl_paintings] No painting found for size "..xsize..","..ysize.."!")
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
local staticdata = {
|
||||||
|
_facing = wallm,
|
||||||
|
_pos = ppos,
|
||||||
|
_motive = pid,
|
||||||
|
_xsize = xsize,
|
||||||
|
_ysize = ysize,
|
||||||
|
}
|
||||||
|
local obj = minetest.add_entity(pposa, "mcl_paintings:painting", minetest.serialize(staticdata))
|
||||||
|
if not obj then
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
if not minetest.settings:get_bool("creative_mode") then
|
||||||
|
itemstack:take_item()
|
||||||
|
end
|
||||||
|
return itemstack
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "mcl_paintings:painting",
|
||||||
|
recipe = {
|
||||||
|
{ "mcl_core:stick", "mcl_core:stick", "mcl_core:stick" },
|
||||||
|
{ "mcl_core:stick", "group:wool", "mcl_core:stick" },
|
||||||
|
{ "mcl_core:stick", "mcl_core:stick", "mcl_core:stick" },
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
2
mods/ENTITIES/mcl_paintings/locale/mcl_paintings.de.tr
Normal file
2
mods/ENTITIES/mcl_paintings/locale/mcl_paintings.de.tr
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# textdomain:mcl_paintings
|
||||||
|
Painting=Gemälde
|
2
mods/ENTITIES/mcl_paintings/locale/template.txt
Normal file
2
mods/ENTITIES/mcl_paintings/locale/template.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# textdomain:mcl_paintings
|
||||||
|
Painting=
|
1
mods/ENTITIES/mcl_paintings/mod.conf
Normal file
1
mods/ENTITIES/mcl_paintings/mod.conf
Normal file
|
@ -0,0 +1 @@
|
||||||
|
name = mcl_paintings
|
55
mods/ENTITIES/mcl_paintings/paintings.lua
Normal file
55
mods/ENTITIES/mcl_paintings/paintings.lua
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
local TS = 16 -- texture size
|
||||||
|
|
||||||
|
mcl_paintings.paintings = {
|
||||||
|
[1] = {
|
||||||
|
[1] = {
|
||||||
|
{ cx = 0, cy = 0 },
|
||||||
|
{ cx = TS, cy = 0 },
|
||||||
|
{ cx = 2*TS, cy = 0 },
|
||||||
|
{ cx = 3*TS, cy = 0 },
|
||||||
|
{ cx = 4*TS, cy = 0 },
|
||||||
|
{ cx = 5*TS, cy = 0 },
|
||||||
|
{ cx = 6*TS, cy = 0 },
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
|
{ cx = 0, cy = 2*TS },
|
||||||
|
{ cx = 2*TS, cy = 2*TS },
|
||||||
|
{ cx = 4*TS, cy = 2*TS },
|
||||||
|
{ cx = 6*TS, cy = 2*TS },
|
||||||
|
{ cx = 8*TS, cy = 2*TS },
|
||||||
|
},
|
||||||
|
[3] = 2,
|
||||||
|
[4] = 2,
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
|
[1] = {
|
||||||
|
{ cx = 0, cy = 4*TS },
|
||||||
|
{ cx = TS, cy = 4*TS },
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
|
{ cx = 0, cy = 8*TS },
|
||||||
|
{ cx = 2*TS, cy = 8*TS },
|
||||||
|
{ cx = 4*TS, cy = 8*TS },
|
||||||
|
{ cx = 6*TS, cy = 8*TS },
|
||||||
|
{ cx = 8*TS, cy = 8*TS },
|
||||||
|
{ cx = 10*TS, cy = 8*TS },
|
||||||
|
},
|
||||||
|
[3] = 2,
|
||||||
|
[4] = {
|
||||||
|
{ cx = 0, cy = 6*TS },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[3] = {
|
||||||
|
[4] = {
|
||||||
|
{ cx = 12*TS, cy = 4*TS },
|
||||||
|
{ cx = 12*TS, cy = 7*TS },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[4] = {
|
||||||
|
[4] = {
|
||||||
|
{ cx = 0, cy = 12*TS },
|
||||||
|
{ cx = 4*TS, cy = 12*TS },
|
||||||
|
{ cx = 8*TS, cy = 12*TS },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
BIN
mods/ENTITIES/mcl_paintings/textures/mcl_paintings_painting.png
Normal file
BIN
mods/ENTITIES/mcl_paintings/textures/mcl_paintings_painting.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 229 B |
BIN
mods/ENTITIES/mcl_paintings/textures/mcl_paintings_paintings.png
Normal file
BIN
mods/ENTITIES/mcl_paintings/textures/mcl_paintings_paintings.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
Loading…
Reference in a new issue