forked from Mineclonia/Mineclonia
Add paintings
This commit is contained in:
parent
d1d7c026e1
commit
bfd2f0ebc7
|
@ -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" },
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# textdomain:mcl_paintings
|
||||
Painting=Gemälde
|
|
@ -0,0 +1,2 @@
|
|||
# textdomain:mcl_paintings
|
||||
Painting=
|
|
@ -0,0 +1 @@
|
|||
name = mcl_paintings
|
|
@ -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 },
|
||||
},
|
||||
},
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 229 B |
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
Loading…
Reference in New Issue