summaryrefslogtreecommitdiff
path: root/init.lua
blob: 8c45e4a4aa6b05304dfb8d4639b9fa95d6999842 (plain)
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
-- minetest/creative/init.lua

-- SETTINGS --

-- Shows the trash slot to players in survival mode
local SURVIVAL_TRASH = true

-- Enables "Freebuild Mode", which allows players to grant/revoke their own creative priv with a button in the inventory.
-- Switching from survival to creative is generally instant, however logging off and back on is required when switching to survival.
-- Note that if players are in creative mode when this is turned off, they will become "stuck" there unless their creative priv is
-- revoked by other means or this is turned back on.
local FREEBUILD_MODE = false

-- "Special" Mode
local ALL_THE_THINGS = false

-- END OF SETTINGS --





-- Register a "creative" priv
minetest.register_privilege("creative", {
	description = "Can use the creative inventory",
	give_to_singleplayer = false,
})

creative_inventory = {}
creative_inventory.creative_inventory_size = 0

-- Determine if the player is running in creative mode
function creative_inventory.is_creative(player)
    playername=player:get_player_name()
	if minetest.check_player_privs(playername, {creative=true}) or
	   minetest.setting_getbool("creative_mode") then
		return true
	end
end

-- Create detached creative inventory after loading all mods
minetest.after(0, function()
	local inv = minetest.create_detached_inventory("creative", {
		allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
			if creative_inventory.is_creative(player) then
				return count
			else
				return 0
			end
		end,
		allow_put = function(inv, listname, index, stack, player)
			return 0
		end,
		allow_take = function(inv, listname, index, stack, player)
			if creative_inventory.is_creative(player) then
				return -1
			else
				return 0
			end
		end,
		on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
		end,
		on_put = function(inv, listname, index, stack, player)
		end,
		on_take = function(inv, listname, index, stack, player)
			print(player:get_player_name().." takes item from creative inventory; listname="..dump(listname)..", index="..dump(index)..", stack="..dump(stack))
			if stack then
				print("stack:get_name()="..dump(stack:get_name())..", stack:get_count()="..dump(stack:get_count()))
			end
		end,
	})
	local creative_list = {}
	for name,def in pairs(minetest.registered_items) do
		if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0)
				and def.description and def.description ~= "" then
			table.insert(creative_list, name)
		end
	end
	table.sort(creative_list)
	inv:set_size("main", #creative_list)
	for _,itemstring in ipairs(creative_list) do
		local stack = ItemStack(itemstring)
		stack:set_count(stack:get_stack_max())
		inv:add_item("main", stack)
	end
	creative_inventory.creative_inventory_size = #creative_list
	print("creative inventory size: "..dump(creative_inventory.creative_inventory_size))
end)

-- Create the trash field
local trash = minetest.create_detached_inventory("creative_trash", {
	-- Allow the stack to be placed and remove it in on_put()
	-- This allows the creative inventory to restore the stack
	allow_put = function(inv, listname, index, stack, player)
			return stack:get_count()
	end,
	on_put = function(inv, listname, index, stack, player)
		inv:set_stack(listname, index, "")
	end,
})
trash:set_size("main", 1)


-- Create the refill field
local refill = minetest.create_detached_inventory("creative_refill", {
	-- Allow the stack to be placed and remove it in on_put()
	-- This allows the creative inventory to restore the stack
	allow_put = function(inv, listname, index, stack, player)
			return stack:get_count()
	end,
	on_put = function(inv, listname, index, stack, player)
	if stack:get_wear() == 0 then
			inv:set_stack(listname, index, "")
			stack:set_count(stack:get_stack_max())
			inv:add_item("main", stack)
	else
		print("Tool detected in refill slot. Current wear is: "..tostring(stack:get_wear())..". Will add "..tostring((-1)*stack:get_wear()).." wear.")
		stack:add_wear((-1)*stack:get_wear())
		print("Tool now has "..tostring(stack:get_wear()).." wear.")
		inv:set_stack(listname, index, "")
		inv:add_item("main", stack)
	end

	end,
})
refill:set_size("main", 1)


creative_inventory.set_creative_formspec = function(player, start_i, pagenum)
	pagenum = math.floor(pagenum)
	local pagemax = math.floor((creative_inventory.creative_inventory_size-1) / (6*4) + 1)
	local formspec = ("size[14,7.5]"..
			--"image[6,0.6;1,2;player.png]"..
			"list[current_player;main;5,3.5;8,4;]"..
			"list[current_player;craft;8,0;3,3;]"..
			"list[current_player;craftpreview;12,1;1,1;]"..
			"list[detached:creative;main;0.3,0.5;4,6;"..tostring(start_i).."]"..
			"label[2.0,6.55;"..tostring(pagenum).."/"..tostring(pagemax).."]"..
			"button[0.3,6.5;1.6,1;creative_prev;<<]"..
			"button[2.7,6.5;1.6,1;creative_next;>>]"..
			"label[5,1.5;Trash:]"..
			"list[detached:creative_trash;main;5,2;1,1;]"..
			"label[5,0;Refill:]"..
			"list[detached:creative_refill;main;5,0.5;1,1;]")
	if (ALL_THE_THINGS) then
		formspec = formspec.."button[6,2.7;2.5,1;clear;Remove _ALL_ the things!]".."image_button[6,1;2,2;all_the_things.png;clear;]"
	else
		formspec = formspec.."button[6,2;2,1;clear;Clear Inventory]"
	end
	if (FREEBUILD_MODE) then
		formspec = formspec.."button[11,0;3,1;creativeoff;Switch to Survival Mode]"
	end
	player:set_inventory_formspec(formspec)
end
creative_inventory.set_survival_formspec = function(player)
	local formspec = player:get_inventory_formspec()
	if (SURVIVAL_TRASH) then
		formspec = formspec.."list[detached:creative_trash;main;0,2;1,1;]".."label[0,1.5;Trash:]"
	end
	if (FREEBUILD_MODE) then
		formspec = formspec.."button[5,0;3,1;creativeon;Switch to Creative Mode]"
	end
	player:set_inventory_formspec(formspec)
end
creative_inventory.clear_inventory = function(player)
		player:get_inventory():set_list("main", {})
		local player_name = player:get_player_name()
		minetest.chat_send_player(player_name, 'Inventory Cleared!')
end
creative_inventory.creative_on = function(player)
	local name = player:get_player_name()
	local privs = minetest.get_player_privs(name)
	privs["creative"] = true
	minetest.set_player_privs(name,privs)
end
creative_inventory.creative_off = function(player)
	local name = player:get_player_name()
	local privs = minetest.get_player_privs(name)
	privs["creative"] = false
	minetest.set_player_privs(name,privs)
end
minetest.register_on_joinplayer(function(player)
	-- If in creative mode, modify player's inventory forms
	if not creative_inventory.is_creative(player) then
		creative_inventory.set_survival_formspec(player)
		return
	end
	creative_inventory.set_creative_formspec(player, 0, 1)
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
	-- Figure out current page from formspec
	local current_page = 0
	local formspec = player:get_inventory_formspec()
	local start_i = string.match(formspec, "list%[detached:creative;main;[%d.]+,[%d.]+;[%d.]+,[%d.]+;(%d+)%]")
	start_i = tonumber(start_i) or 0

	if fields.clear then
		creative_inventory.clear_inventory(player)
	end
	if fields.creativeon then
		creative_inventory.creative_on(player)
	end
	if fields.creativeoff then
		creative_inventory.creative_off(player)
	end
	if creative_inventory.is_creative(player) then
		if fields.creative_prev then
			start_i = start_i - 4*6
		end
		if fields.creative_next then
			start_i = start_i + 4*6
		end

		if start_i < 0 then
			start_i = start_i + 4*6
		end
		if start_i >= creative_inventory.creative_inventory_size then
			start_i = start_i - 4*6
		end
		
		if start_i < 0 or start_i >= creative_inventory.creative_inventory_size then
			start_i = 0
		end

		creative_inventory.set_creative_formspec(player, start_i, start_i / (6*4) + 1)
	end
end)

if minetest.setting_getbool("creative_mode") then
	
	minetest.register_item(":", {
		type = "none",
		wield_image = "wieldhand.png",
		wield_scale = {x=1,y=1,z=2.5},
		tool_capabilities = {
			full_punch_interval = 0.5,
			max_drop_level = 3,
			groupcaps = {
				crumbly = {times={[1]=0.5, [2]=0.5, [3]=0.5}, uses=0, maxlevel=3},
				cracky = {times={[1]=0.5, [2]=0.5, [3]=0.5}, uses=0, maxlevel=3},
				snappy = {times={[1]=0.5, [2]=0.5, [3]=0.5}, uses=0, maxlevel=3},
				choppy = {times={[1]=0.5, [2]=0.5, [3]=0.5}, uses=0, maxlevel=3},
				oddly_breakable_by_hand = {times={[1]=0.5, [2]=0.5, [3]=0.5}, uses=0, maxlevel=3},
			},
			damage_groups = {fleshy = 10},
		}
	})
	
	function minetest.handle_node_drops(pos, drops, digger)
		if not digger or not digger:is_player() then
			return
		end
		local inv = digger:get_inventory()
		if inv then
			for _,item in ipairs(drops) do
				item = ItemStack(item):get_name()
				if not inv:contains_item("main", item) then
					inv:add_item("main", item)
				end
			end
		end
	end
	
end