4 Copyright (C) 2015 - Auke Kok <sofar@foo-projects.org>
6 "frame" is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of
9 the license, or (at your option) any later version.
13 local S
= minetest
.get_translator("frame")
17 -- handle node removal from frame
18 local function frame_on_punch(pos
, node
, puncher
, pointed_thing
)
19 local name
= puncher
:get_player_name()
20 if puncher
and not minetest
.check_player_privs(puncher
, "protection_bypass") then
21 if minetest
.is_protected(pos
, name
) then
22 minetest
.record_protection_violation(pos
, name
)
27 local def
= minetest
.registered_nodes
[node
.name
]
30 local meta
= minetest
.get_meta(pos
)
31 if puncher
:get_player_control().sneak
and boxes
.players_editing_boxes
[name
] then
33 local idef
= minetest
.registered_nodes
[def
.frame_contents
]
34 if idef
and not(idef
.groups
.hand
or idef
.groups
.axe
or idef
.groups
.shovel
or idef
.groups
.pickaxe
or idef
.groups
.torch
) then
35 meta
:set_int("locked", 1)
36 minetest
.chat_send_player(name
, S("The frame contains an item the player can not obtain, therefore remains locked."))
38 elseif meta
:get_int("locked") == 1 then
39 meta
:set_int("locked", 0)
40 minetest
.chat_send_player(name
, S("Frame is now unlocked."))
43 meta
:set_int("locked", 1)
44 minetest
.chat_send_player(name
, S("Frame is now locked."))
49 if meta
:get_int("locked") == 1 then
50 if not boxes
.players_editing_boxes
[name
] then
55 -- preserve itemstack metadata and wear
56 local wear
= meta
:get_int("wear")
57 local item
= ItemStack(def
.frame_contents
)
61 local metadata
= meta
:get_string("metadata")
62 if metadata
~= "" then
63 item
:set_metadata(metadata
)
66 --minetest.handle_node_drops(pos, {item}, puncher)
67 local inv
= puncher
:get_inventory()
68 if inv
:room_for_item("main", item
) then
69 inv
:add_item("main", item
)
70 --minetest.sound_play(def.sounds.dug, {pos = pos})
71 minetest
.swap_node(pos
, {name
= "frame:empty", param2
= node
.param2
})
76 ["tools:player"] = true,
77 ["tools:bulk"] = true,
78 ["tools:grow"] = true,
81 -- handle node insertion into empty frame
82 local function frame_on_rightclick(pos
, node
, clicker
, itemstack
, pointed_thing
)
83 if clicker
and not minetest
.check_player_privs(clicker
, "protection_bypass") then
84 local name
= clicker
:get_player_name()
85 if minetest
.is_protected(pos
, name
) then
86 minetest
.record_protection_violation(pos
, name
)
91 local nodename
= itemstack
:get_name()
96 if frame_admin
[nodename
] and not minetest
.check_player_privs(clicker
, "server") then
100 local name
= "frame:" .. nodename
:gsub(":", "_")
101 local def
= minetest
.registered_nodes
[name
]
103 minetest
.chat_send_player(clicker
:get_player_name(), S("This item can not be inserted in a frame."))
107 local meta
= minetest
.get_meta(pos
)
108 local idef
= minetest
.registered_nodes
[nodename
]
109 if idef
and not(idef
.groups
.hand
or idef
.groups
.axe
or idef
.groups
.shovel
or idef
.groups
.pickaxe
or idef
.groups
.torch
) then
110 meta
:set_int("locked", 1)
111 minetest
.chat_send_player(clicker
:get_player_name(), S("Item inserted into frame is not obtainable, frame locked."))
114 local wear
= itemstack
:get_wear()
116 meta
:set_int("wear", wear
)
118 local metadata
= itemstack
:get_metadata()
119 if metadata
~= "" then
120 meta
:set_string("metadata", metadata
)
123 --minetest.sound_play(def.sounds.place, {pos = pos})
124 minetest
.swap_node(pos
, {name
= name
, param2
= node
.param2
})
125 if not minetest
.setting_getbool("creative_mode") then
126 itemstack
:take_item()
131 function frame
.register(name
)
132 assert(name
, "no content passed")
135 local def
= minetest
.registered_nodes
[name
]
138 def
= minetest
.registered_items
[name
]
139 assert(def
, "not a thing: ".. name
)
140 assert(def
.inventory_image
, "no inventory image for " .. name
)
143 {name
= "frame_frame.png"},
144 {name
= def
.inventory_image
},
145 {name
= "itb_blank.png"},
146 {name
= "itb_blank.png"},
147 {name
= "itb_blank.png"},
151 if def
.inventory_image
~= "" then
152 -- custom inventory override image first.
154 {name
= "frame_frame.png"},
155 {name
= def
.inventory_image
or "itb_blank.png"},
156 {name
= "itb_blank.png"},
157 {name
= "itb_blank.png"},
158 {name
= "itb_blank.png"},
160 elseif def
.drawtype
~= "normal" then
161 -- use tiles[1] only, but on frame
163 {name
= "frame_frame.png"},
164 {name
= def
.tiles
[1] and def
.tiles
[1].name
or def
.tiles
[1] or "itb_blank.png"},
165 {name
= "itb_blank.png"},
166 {name
= "itb_blank.png"},
167 {name
= "itb_blank.png"},
169 else -- type(def.tiles[1]) == "table" then
172 {name
= "frame_frame.png"},
173 {name
= "itb_blank.png"},
174 {name
= def
.tiles
[1] and def
.tiles
[1].name
or def
.tiles
[1]
176 {name
= def
.tiles
[2] and def
.tiles
[2].name
or def
.tiles
[1]
177 or def
.tiles
[1] and def
.tiles
[1].name
or def
.tiles
[1]
179 {name
= def
.tiles
[3] and def
.tiles
[3].name
or def
.tiles
[3]
180 or def
.tiles
[2] and def
.tiles
[2].name
or def
.tiles
[2]
181 or def
.tiles
[1] and def
.tiles
[1].name
or def
.tiles
[1]
186 assert(def
, name
.. " is not a known node or item")
188 local desc
= def
.description
189 local nodename
= def
.name
:gsub(":", "_")
191 minetest
.register_node(":frame:" .. nodename
, {
192 description
= S("Frame with @1", desc
),
194 use_texture_alpha
= "clip",
198 paramtype2
= "facedir",
199 sunlight_propagates
= true,
202 fixed
= {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2},
206 fixed
= {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2},
208 groups
= {oddly_breakable_by_hand
= 1, snappy
= 3, not_in_creative_inventory
= 1, frame_with_content
= 1},
209 frame_contents
= name
,
210 on_punch
= frame_on_punch
,
211 on_reveal
= function(n
, pos
)
212 local meta
= minetest
.get_meta(pos
)
214 if meta
:get_int("locked") == 1 then
217 minetest
.chat_send_player(n
, minetest
.colorize(
218 "#88ff44", "> locked = " .. locked
221 sounds
= sounds
.wood
,
226 minetest
.register_node("frame:empty", {
227 description
= S("Frame"),
231 {name
= "frame_frame.png"},
232 {name
= "itb_blank.png"},
233 {name
= "itb_blank.png"},
234 {name
= "itb_blank.png"},
235 {name
= "itb_blank.png"},
237 use_texture_alpha
= "clip",
239 paramtype2
= "facedir",
240 sunlight_propagates
= true,
243 fixed
= {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2},
247 fixed
= {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2},
249 groups
= {oddly_breakable_by_hand
= 3, cracky
= 1},
250 on_rightclick
= frame_on_rightclick
,
251 sounds
= sounds
.wood
,
255 frame
.register("frame:empty")
257 minetest
.register_abm({
258 label
= "frame:content_obtainable",
259 nodenames
= {"group:frame_with_content"},
263 action
= function(pos
, node
)
264 local meta
= minetest
.get_meta(pos
)
265 if meta
:get_int("locked") == 1 then
268 minetest
.add_particle({
269 pos
= vector
.add(pos
, math
.random(50)/100 - 0.25),
270 minpos
= {x
= math
.floor(pos
.x
) - 0.4, y
= math
.floor(pos
.y
) - 0.4, z
= math
.floor(pos
.z
) - 0.4},
271 maxpos
= {x
= math
.floor(pos
.x
) + 0.4, y
= math
.floor(pos
.y
) + 0.4, z
= math
.floor(pos
.z
) + 0.4},
272 velocity
= {x
= 0, y
= 0, z
= 0},
273 expirationtime
= 0.78,
274 size
= math
.random(10)/5 + 1,
275 texture
= "frame_effect_animated.png",