-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathinit.lua
289 lines (225 loc) · 10.8 KB
/
init.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
--[[
Replacement tool for creative building (Mod for MineTest)
Copyright (C) 2013 Sokomine
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
--]]
-- Version 3.0
-- Changelog:
-- 02.09.2021 * Added a history of stored patterns (not saved over server restart)
-- * Added a menu to select a history entry. It is accessable via AUX1 + left click.
-- * Removed deprecated functions get/set_metadata(..) and renamed metadata to pattern
-- 29.09.2021 * AUX1 key works now same as SNEAK key for storing new pattern (=easier when flying)
-- * The description of the tool now shows which pattern is stored
-- * The description of the stored pattern is more human readable
-- 09.12.2017 * Got rid of outdated minetest.env
-- * Fixed error in protection function.
-- * Fixed minor bugs.
-- * Added blacklist
-- 02.10.2014 * Some more improvements for inspect-tool. Added craft-guide.
-- 01.10.2014 * Added inspect-tool.
-- 12.01.2013 * If digging the node was unsuccessful, then the replacement will now fail
-- (instead of destroying the old node with its metadata; i.e. chests with content)
-- 20.11.2013 * if the server version is new enough, minetest.is_protected is used
-- in order to check if the replacement is allowed
-- 24.04.2013 * param1 and param2 are now stored
-- * hold sneak + right click to store new pattern
-- * right click: place one of the itmes
-- * receipe changed
-- * inventory image added
-- adds a function to check ownership of a node; taken from VanessaEs homedecor mod
dofile(minetest.get_modpath("replacer").."/check_owner.lua");
replacer = {};
replacer.default_dirt = "default:dirt"
replacer.blacklist = {};
-- playing with tnt and creative building are usually contradictory
-- (except when doing large-scale landscaping in singleplayer)
replacer.blacklist[ "tnt:boom"] = true;
replacer.blacklist[ "tnt:gunpowder"] = true;
replacer.blacklist[ "tnt:gunpowder_burning"] = true;
replacer.blacklist[ "tnt:tnt"] = true;
-- prevent accidental replacement of your protector
replacer.blacklist[ "protector:protect"] = true;
replacer.blacklist[ "protector:protect2"] = true;
-- adds a tool for inspecting nodes and entities
dofile(minetest.get_modpath("replacer").."/inspect.lua");
-- adds a formspec with a history function (accessible with AUX1 + left click)
dofile(minetest.get_modpath("replacer").."/fs_history.lua");
-- adds support for the circular saw from moreblocks and similar nodes
-- and allows to replace the *material* while keeping shape - or vice versa
dofile(minetest.get_modpath("replacer").."/mode_of_replacement.lua");
minetest.register_tool( "replacer:replacer",
{
description = "Node replacement tool",
groups = {},
inventory_image = "replacer_replacer.png",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 1, -- it has to store information - thus only one can be stacked
liquids_pointable = true, -- it is ok to painit in/with water
--[[
-- the tool_capabilities are of nearly no intrest here
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}
}
},
--]]
node_placement_prediction = nil,
on_place = function(itemstack, placer, pointed_thing)
if( placer == nil or pointed_thing == nil) then
return itemstack; -- nothing consumed
end
local name = placer:get_player_name();
--minetest.chat_send_player( name, "You PLACED this on "..minetest.serialize( pointed_thing )..".");
local keys=placer:get_player_control();
-- just place the stored node if no new one is to be selected
if( not( keys["sneak"] ) and not( keys["aux1"])) then
return replacer.replace( itemstack, placer, pointed_thing, 0 ); end
if( pointed_thing.type ~= "node" ) then
minetest.chat_send_player( name, " Error: No node selected.");
return nil;
end
local pos = minetest.get_pointed_thing_position( pointed_thing, false ); -- node under
local node = minetest.get_node_or_nil( pos );
local pattern = replacer.default_dirt.." 0 0";
if( node ~= nil and node.name ) then
pattern = node.name..' '..node.param1..' '..node.param2;
end
return replacer.set_to(name, pattern, placer, itemstack) -- nothing consumed but data changed
end,
on_use = function(itemstack, user, pointed_thing)
return replacer.replace( itemstack, user, pointed_thing, false );
end,
})
replacer.replace = function( itemstack, user, pointed_thing, mode )
if( user == nil or pointed_thing == nil) then
return nil;
end
local name = user:get_player_name();
if( pointed_thing.type ~= "node" ) then
minetest.chat_send_player( name, " Error: No node.");
return nil;
end
local pos = minetest.get_pointed_thing_position( pointed_thing, mode );
local node = minetest.get_node_or_nil( pos );
if( node == nil ) then
minetest.chat_send_player( name, "Error: Target node not yet loaded. Please wait a moment for the server to catch up.");
return nil;
end
local meta = itemstack:get_meta()
local pattern = meta:get_string("pattern")
-- make sure it is defined
if(not(pattern) or pattern == "") then
pattern = replacer.default_dirt.." 0 0";
end
local keys=user:get_player_control();
if( keys["aux1"]) then
minetest.show_formspec(name, "replacer:menu", replacer.get_formspec(name, pattern, user))
return nil
end
-- regain information about nodename, param1 and param2
local daten = pattern:split( " " );
-- the old format stored only the node name
if( #daten < 3 ) then
daten[2] = 0;
daten[3] = 0;
end
-- if someone else owns that node then we can not change it
if( replacer_homedecor_node_is_owned(pos, user)) then
return nil;
end
local daten = replacer.get_new_node_data(node, daten, name)
-- nothing to replace
if(not(daten)) then
return
end
if( node.name and node.name ~= "" and replacer.blacklist[ node.name ]) then
minetest.chat_send_player( name, "Replacing blocks of the type '"..( node.name or "?" )..
"' is not allowed on this server. Replacement failed.");
return nil;
end
if( replacer.blacklist[ daten[1] ]) then
minetest.chat_send_player( name, "Placing blocks of the type '"..( daten[1] or "?" )..
"' with the replacer is not allowed on this server. Replacement failed.");
return nil;
end
-- do not replace if there is nothing to be done
if( node.name == daten[1] ) then
-- the node itshelf remains the same, but the orientation was changed
if( node.param1 ~= daten[2] or node.param2 ~= daten[3] ) then
minetest.add_node( pos, { name = node.name, param1 = daten[2], param2 = daten[3] } );
end
return nil;
end
-- in survival mode, the player has to provide the node he wants to place
if( not(minetest.settings:get_bool("creative_mode") )
and not( minetest.check_player_privs( name, {creative=true}))) then
-- players usually don't carry dirt_with_grass around; it's safe to assume normal dirt here
-- fortunately, dirt and dirt_with_grass does not make use of rotation
if( daten[1] == "default:dirt_with_grass" or daten[1] == "mcl_core:dirt_with_grass") then
daten[1] = replacer.default_dirt
pattern = replacer.default_dirt.." 0 0";
end
-- does the player carry at least one of the desired nodes with him?
if( not( user:get_inventory():contains_item("main", daten[1]))) then
minetest.chat_send_player( name, "You have no further '"..( daten[1] or "?" ).."'. Replacement failed.");
return nil;
end
-- give the player the item by simulating digging if possible
if( node.name ~= "air"
and node.name ~= "ignore") then
minetest.node_dig( pos, node, user );
local digged_node = minetest.get_node_or_nil( pos );
if( not( digged_node )
or digged_node.name == node.name ) then
-- some nodes - like liquids - cannot be digged. but they are buildable_to and
-- thus can be replaced
local node_def = minetest.registered_nodes[node.name]
if(not(node_def) or not(node_def.buildable_to)) then
minetest.chat_send_player( name, "Replacing '"..( node.name or "air" ).."' with '"..( pattern or "?" ).."' failed. Unable to remove old node.");
return nil;
end
end
end
-- consume the item
user:get_inventory():remove_item("main", daten[1].." 1");
end
minetest.add_node( pos, { name = daten[1], param1 = daten[2], param2 = daten[3] } );
return nil; -- no item shall be removed from inventory
end
-- do the exception for MineClone first...
if(minetest.registered_nodes["mcl_chests:chest"]) then
replacer.default_dirt = "mcl_core:dirt"
minetest.register_craft({
output = 'replacer:replacer',
recipe = {
{ 'mcl_chests:chest', '', '' },
{ '', 'mcl_core:stick', '' },
{ '', '', 'mcl_chests:chest' },
}
})
-- then the normal receipe
elseif(minetest.registered_nodes["default:chest"]) then
minetest.register_craft({
output = 'replacer:replacer',
recipe = {
{ 'default:chest', '', '' },
{ '', 'default:stick', '' },
{ '', '', 'default:chest' },
}
})
end