Fix `[sheet` usage in particle spawner.
[insidethebox.git] / mods / frame / init.lua
blobb01162639ce17fd128885f33f5846d8612459495
2 --[[
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.
11 --]]
13 local S = minetest.get_translator("frame")
15 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)
23 return false
24 end
25 end
27 local def = minetest.registered_nodes[node.name]
29 -- lock/unlock
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."))
37 return false
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."))
41 return false
42 else
43 meta:set_int("locked", 1)
44 minetest.chat_send_player(name, S("Frame is now locked."))
45 return false
46 end
47 end
49 if meta:get_int("locked") == 1 then
50 if not boxes.players_editing_boxes[name] then
51 return false
52 end
53 end
55 -- preserve itemstack metadata and wear
56 local wear = meta:get_int("wear")
57 local item = ItemStack(def.frame_contents)
58 if wear then
59 item:set_wear(wear)
60 end
61 local metadata = meta:get_string("metadata")
62 if metadata ~= "" then
63 item:set_metadata(metadata)
64 end
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})
72 end
73 end
75 local frame_admin = {
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)
87 return false
88 end
89 end
91 local nodename = itemstack:get_name()
92 if not nodename then
93 return false
94 end
96 if frame_admin[nodename] and not minetest.check_player_privs(clicker, "server") then
97 return false
98 end
100 local name = "frame:" .. nodename:gsub(":", "_")
101 local def = minetest.registered_nodes[name]
102 if not def then
103 minetest.chat_send_player(clicker:get_player_name(), S("This item can not be inserted in a frame."))
104 return itemstack
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()
115 if wear then
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()
128 return itemstack
131 function frame.register(name)
132 assert(name, "no content passed")
133 local tiles
135 local def = minetest.registered_nodes[name]
136 if not def then
137 -- item?
138 def = minetest.registered_items[name]
139 assert(def, "not a thing: ".. name)
140 assert(def.inventory_image, "no inventory image for " .. name)
142 tiles = {
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"},
149 else
150 -- node
151 if def.inventory_image ~= "" then
152 -- custom inventory override image first.
153 tiles = {
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
162 tiles = {
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
170 -- multiple tiles
171 tiles = {
172 {name = "frame_frame.png"},
173 {name = "itb_blank.png"},
174 {name = def.tiles[1] and def.tiles[1].name or def.tiles[1]
175 or "itb_blank.png"},
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]
178 or "itb_blank.png"},
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]
182 or "itb_blank.png"},
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),
193 drawtype = "mesh",
194 use_texture_alpha = "clip",
195 mesh = "frame.obj",
196 tiles = tiles,
197 paramtype = "light",
198 paramtype2 = "facedir",
199 sunlight_propagates = true,
200 collision_box = {
201 type = "fixed",
202 fixed = {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2},
204 selection_box = {
205 type = "fixed",
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)
213 local locked = "no"
214 if meta:get_int("locked") == 1 then
215 locked = "yes"
217 minetest.chat_send_player(n, minetest.colorize(
218 "#88ff44", "> locked = " .. locked
220 end,
221 sounds = sounds.wood,
225 -- empty frame
226 minetest.register_node("frame:empty", {
227 description = S("Frame"),
228 drawtype = "mesh",
229 mesh = "frame.obj",
230 tiles = {
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",
238 paramtype = "light",
239 paramtype2 = "facedir",
240 sunlight_propagates = true,
241 collision_box = {
242 type = "fixed",
243 fixed = {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2},
245 selection_box = {
246 type = "fixed",
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,
254 -- inception!
255 frame.register("frame:empty")
257 minetest.register_abm({
258 label = "frame:content_obtainable",
259 nodenames = {"group:frame_with_content"},
260 interval = 0.1,
261 chance = 50,
262 catch_up = false,
263 action = function(pos, node)
264 local meta = minetest.get_meta(pos)
265 if meta:get_int("locked") == 1 then
266 return
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",
276 glow = 13,
277 animation = {
278 type = "sheet_2d",
279 frames_w = 8,
280 frames_h = 1,
281 frame_length = 0.1,
284 end,