]> git.lizzy.rs Git - minetest.git/blob - data/mods/experimental/init.lua
Ban and Auth managers use infostream rather than dstream
[minetest.git] / data / mods / experimental / init.lua
1 --
2 -- Experimental things
3 --
4
5 -- For testing random stuff
6
7 experimental = {}
8
9 function on_step(dtime)
10         -- print("experimental on_step")
11         --[[
12         objs = minetest.env:get_objects_inside_radius({x=0,y=0,z=0}, 10)
13         for k, obj in pairs(objs) do
14                 name = obj:get_player_name()
15                 if name then
16                         print(name.." at "..dump(obj:getpos()))
17                         print(name.." dir: "..dump(obj:get_look_dir()))
18                         print(name.." pitch: "..dump(obj:get_look_pitch()))
19                         print(name.." yaw: "..dump(obj:get_look_yaw()))
20                 else
21                         print("Some object at "..dump(obj:getpos()))
22                 end
23         end
24         --]]
25         --[[
26         if experimental.t1 == nil then
27                 experimental.t1 = 0
28         end
29         experimental.t1 = experimental.t1 + dtime
30         if experimental.t1 >= 2 then
31                 experimental.t1 = experimental.t1 - 2
32                 minetest.log("time of day is "..minetest.env:get_timeofday())
33                 if experimental.day then
34                         minetest.log("forcing day->night")
35                         experimental.day = false
36                         minetest.env:set_timeofday(0.0)
37                 else
38                         minetest.log("forcing night->day")
39                         experimental.day = true
40                         minetest.env:set_timeofday(0.5)
41                 end
42                 minetest.log("time of day is "..minetest.env:get_timeofday())
43         end
44         --]]
45 end
46 minetest.register_globalstep(on_step)
47
48 -- An example furnace-thing implemented in Lua
49
50 --[[
51 minetest.register_node("experimental:luafurnace", {
52         tile_images = {"default_lava.png", "default_furnace_side.png",
53                 "default_furnace_side.png", "default_furnace_side.png",
54                 "default_furnace_side.png", "default_furnace_front.png"},
55         --inventory_image = "furnace_front.png",
56         inventory_image = minetest.inventorycube("default_furnace_front.png"),
57         paramtype = "facedir_simple",
58         metadata_name = "generic",
59         material = minetest.digprop_stonelike(3.0),
60 })
61
62 minetest.register_on_placenode(function(pos, newnode, placer)
63         if newnode.name == "experimental:luafurnace" then
64                 local meta = minetest.env:get_meta(pos)
65                 meta:inventory_set_list("fuel", {""})
66                 meta:inventory_set_list("src", {""})
67                 meta:inventory_set_list("dst", {"","","",""})
68                 meta:set_inventory_draw_spec(
69                         "invsize[8,9;]"
70                         .."list[current_name;fuel;2,3;1,1;]"
71                         .."list[current_name;src;2,1;1,1;]"
72                         .."list[current_name;dst;5,1;2,2;]"
73                         .."list[current_player;main;0,5;8,4;]"
74                 )
75                 
76                 local total_cooked = 0;
77                 meta:set_string("total_cooked", total_cooked)
78                 meta:set_infotext("Lua Furnace: total cooked: "..total_cooked)
79         end
80 end)
81
82 minetest.register_abm({
83         nodenames = {"experimental:luafurnace"},
84         interval = 1.0,
85         chance = 1,
86         action = function(pos, node, active_object_count, active_object_count_wider)
87                 local meta = minetest.env:get_meta(pos)
88                 for i, name in ipairs({
89                                 "fuel_totaltime",
90                                 "fuel_time",
91                                 "src_totaltime",
92                                 "src_time"
93                 }) do
94                         if not meta:get_string(name) then
95                                 meta:set_string(name, 0)
96                         end
97                 end
98
99                 local inv = meta:get_inventory()
100                 
101                 local fuelitem = inv:get_stack("fuel", 1):peek_item()
102                 local srcitem = inv:get_stack("src", 1):peek_item()
103                 --print("fuelitem="..dump(fuelitem))
104                 --print("srcitem="..dump(srcitem))
105                 
106                 local was_active = false
107
108                 local src_cooktime = -1
109                 local result_stackstring = nil
110                 
111                 if srcitem then
112                         local prop = get_item_definition(srcitem)
113                         if prop and prop.cookresult_itemstring ~= "" then
114                                 result_stackstring = prop.cookresult_itemstring
115                                 src_cooktime = prop.furnace_cooktime or 3
116                         end
117                 end
118
119                 print("src_cooktime="..dump(src_cooktime))
120                 print("result_stackstring="..dump(result_stackstring))
121
122                 if tonumber(meta:get_string("fuel_time")) < tonumber(meta:get_string("fuel_totaltime")) then
123                         was_active = true
124                         meta:set_string("fuel_time", tonumber(meta:get_string("fuel_time")) + 1)
125                         meta:set_string("src_time", tonumber(meta:get_string("src_time")) + 1)
126                         --print("result_stackstring="..dump(result_stackstring))
127                         --print('tonumber(meta:get_string("src_time"))='..dump(tonumber(meta:get_string("src_time"))))
128                         --print("src_cooktime="..dump(src_cooktime))
129                         if result_stackstring and tonumber(meta:get_string("src_time")) >= src_cooktime and src_cooktime >= 0 then
130                                 -- Put result in "dst" list
131                                 success = inv:autoinsert_stackstring("dst", result_stackstring)
132                                 if not success then
133                                         print("Could not autoinsert '"..result_stackstring.."'")
134                                 end
135                                 -- If succeeded, take stuff from "src" list
136                                 if success then
137                                         srcstack = inv:get_stack("src", 1)
138                                         srcstack:take_item()
139                                         inv:set_stack("src", 1, srcstack)
140                                 end
141                                 meta:set_string("src_time", 0)
142                         end
143                 end
144                 
145                 if tonumber(meta:get_string("fuel_time")) < tonumber(meta:get_string("fuel_totaltime")) then
146                         meta:set_infotext("Furnace active: "..(tonumber(meta:get_string("fuel_time"))/tonumber(meta:get_string("fuel_totaltime"))*100).."%")
147                         return
148                 end
149
150                 local srcitem = inv:get_stack("src", 1):peek_item()
151
152                 local src_cooktime = 0
153                 local result_stackstring = nil
154                 
155                 if srcitem then
156                         local prop = get_item_definition(srcitem)
157                         if prop and prop.cookresult_itemstring ~= "" then
158                                 result_stackstring = prop.cookresult_itemstring
159                                 src_cooktime = prop.furnace_cooktime or 3
160                         end
161                 end
162
163                 local fuelitem = inv:get_stack("fuel", 1):peek_item()
164
165                 if not result_stackstring or not fuelitem then
166                         if was_active then
167                                 meta:set_infotext("Furnace is empty")
168                         end
169                         return
170                 end
171
172                 local burntime = -1
173                 if fuelitem then
174                         local prop = get_item_definition(fuelitem)
175                         if prop then
176                                 burntime = prop.furnace_burntime or -1
177                         end
178                 end
179
180                 if burntime <= 0 then
181                         meta:set_infotext("Furnace out of fuel")
182                         return
183                 end
184
185                 meta:set_string("fuel_totaltime", burntime)
186                 meta:set_string("fuel_time", 0)
187                 
188                 local stack = inv:get_stack("fuel", 1)
189                 stack:take_item()
190                 inv:set_stack("fuel", 1, stack)
191         end,
192 })
193 minetest.register_abm({
194         nodenames = {"experimental:luafurnace"},
195         interval = 1.0,
196         chance = 1,
197         action = function(pos, node, active_object_count, active_object_count_wider)
198                 local meta = minetest.env:get_meta(pos)
199                 local fuellist = meta:inventory_get_list("fuel")
200                 local srclist = meta:inventory_get_list("src")
201                 local dstlist = meta:inventory_get_list("dst")
202                 if fuellist == nil or srclist == nil or dstlist == nil then
203                         return
204                 end
205                 _, srcitem = stackstring_take_item(srclist[1])
206                 _, fuelitem = stackstring_take_item(fuellist[1])
207                 if not srcitem or not fuelitem then return end
208                 if fuelitem.type == "node" then
209                         local prop = minetest.registered_nodes[fuelitem.name]
210                         if prop == nil then return end
211                         if prop.furnace_burntime < 0 then return end
212                 else
213                         return
214                 end
215                 local resultstack = nil
216                 if srcitem.type == "node" then
217                         local prop = minetest.registered_nodes[srcitem.name]
218                         if prop == nil then return end
219                         if prop.cookresult_item == "" then return end
220                         resultstack = prop.cookresult_item
221                 else
222                         return
223                 end
224
225                 if resultstack == nil then
226                         return
227                 end
228
229                 dstlist[1], success = stackstring_put_stackstring(dstlist[1], resultstack)
230                 if not success then
231                         return
232                 end
233
234                 fuellist[1], _ = stackstring_take_item(fuellist[1])
235                 srclist[1], _ = stackstring_take_item(srclist[1])
236
237                 meta:inventory_set_list("fuel", fuellist)
238                 meta:inventory_set_list("src", srclist)
239                 meta:inventory_set_list("dst", dstlist)
240
241                 local total_cooked = meta:get_string("total_cooked")
242                 total_cooked = tonumber(total_cooked) + 1
243                 meta:set_string("total_cooked", total_cooked)
244                 meta:set_infotext("Lua Furnace: total cooked: "..total_cooked)
245         end,
246 })
247 minetest.register_craft({
248         output = 'node "experimental:luafurnace" 1',
249         recipe = {
250                 {'node "default:cobble"', 'node "default:cobble"', 'node "default:cobble"'},
251                 {'node "default:cobble"', 'node "default:steel_ingot"', 'node "default:cobble"'},
252                 {'node "default:cobble"', 'node "default:cobble"', 'node "default:cobble"'},
253         }
254 })
255 --]]
256
257 --
258 -- Random stuff
259 --
260
261 --[[
262 minetest.register_tool("experimental:horribletool", {
263         image = "default_lava.png",
264         basetime = 2.0
265         dt_weight = 0.2
266         dt_crackiness = 0.2
267         dt_crumbliness = 0.2
268         dt_cuttability = 0.2
269         basedurability = 50
270         dd_weight = -5
271         dd_crackiness = -5
272         dd_crumbliness = -5
273         dd_cuttability = -5
274 })
275 --]]
276
277 --
278 -- TNT (not functional)
279 --
280
281 minetest.register_craft({
282         output = 'experimental:tnt',
283         recipe = {
284                 {'default:wood'},
285                 {'default:coal_lump'},
286                 {'default:wood'}
287         }
288 })
289
290 minetest.register_node("experimental:tnt", {
291         tile_images = {"default_tnt_top.png", "default_tnt_bottom.png",
292                         "default_tnt_side.png", "default_tnt_side.png",
293                         "default_tnt_side.png", "default_tnt_side.png"},
294         inventory_image = minetest.inventorycube("default_tnt_top.png",
295                         "default_tnt_side.png", "default_tnt_side.png"),
296         drop = '', -- Get nothing
297         material = {
298                 diggability = "not",
299         },
300 })
301
302 minetest.register_on_punchnode(function(p, node)
303         if node.name == "experimental:tnt" then
304                 minetest.env:remove_node(p)
305                 minetest.env:add_entity(p, "experimental:tnt")
306                 nodeupdate(p)
307         end
308 end)
309
310 local TNT = {
311         -- Static definition
312         physical = true, -- Collides with things
313         -- weight = 5,
314         collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
315         visual = "cube",
316         textures = {"default_tnt_top.png", "default_tnt_bottom.png",
317                         "default_tnt_side.png", "default_tnt_side.png",
318                         "default_tnt_side.png", "default_tnt_side.png"},
319         -- Initial value for our timer
320         timer = 0,
321         -- Number of punches required to defuse
322         health = 1,
323         blinktimer = 0,
324         blinkstatus = true,
325 }
326
327 -- Called when a TNT object is created
328 function TNT:on_activate(staticdata)
329         print("TNT:on_activate()")
330         self.object:setvelocity({x=0, y=4, z=0})
331         self.object:setacceleration({x=0, y=-10, z=0})
332         self.object:settexturemod("^[brighten")
333         self.object:set_armor_groups({immortal=1})
334 end
335
336 -- Called periodically
337 function TNT:on_step(dtime)
338         --print("TNT:on_step()")
339         self.timer = self.timer + dtime
340         self.blinktimer = self.blinktimer + dtime
341         if self.blinktimer > 0.5 then
342                 self.blinktimer = self.blinktimer - 0.5
343                 if self.blinkstatus then
344                         self.object:settexturemod("")
345                 else
346                         self.object:settexturemod("^[brighten")
347                 end
348                 self.blinkstatus = not self.blinkstatus
349         end
350 end
351
352 -- Called when object is punched
353 function TNT:on_punch(hitter)
354         print("TNT:on_punch()")
355         self.health = self.health - 1
356         if self.health <= 0 then
357                 self.object:remove()
358                 hitter:get_inventory():add_item("main", "experimental:tnt")
359                 --hitter:set_hp(hitter:get_hp() - 1)
360         end
361 end
362
363 -- Called when object is right-clicked
364 function TNT:on_rightclick(clicker)
365         --pos = self.object:getpos()
366         --pos = {x=pos.x, y=pos.y+0.1, z=pos.z}
367         --self.object:moveto(pos, false)
368 end
369
370 --print("TNT dump: "..dump(TNT))
371 --print("Registering TNT");
372 minetest.register_entity("experimental:tnt", TNT)
373
374 -- Add TNT's old name also
375 minetest.register_alias("TNT", "experimental:tnt")
376
377 --
378 -- The dummyball!
379 --
380
381 minetest.register_entity("experimental:dummyball", {
382         -- Static definition
383         hp_max = 20,
384         physical = false,
385         collisionbox = {-0.4,-0.4,-0.4, 0.4,0.4,0.4},
386         visual = "sprite",
387         visual_size = {x=1, y=1},
388         textures = {"experimental_dummyball.png"},
389         spritediv = {x=1, y=3},
390         initial_sprite_basepos = {x=0, y=0},
391         -- Dynamic variables
392         phase = 0,
393         phasetimer = 0,
394
395         on_activate = function(self, staticdata)
396                 minetest.log("Dummyball activated!")
397         end,
398
399         on_step = function(self, dtime)
400                 self.phasetimer = self.phasetimer + dtime
401                 if self.phasetimer > 2.0 then
402                         self.phasetimer = self.phasetimer - 2.0
403                         self.phase = self.phase + 1
404                         if self.phase >= 3 then
405                                 self.phase = 0
406                         end
407                         self.object:setsprite({x=0, y=self.phase})
408                         phasearmor = {
409                                 [0]={cracky=3},
410                                 [1]={crumbly=3},
411                                 [2]={fleshy=3}
412                         }
413                         self.object:set_armor_groups(phasearmor[self.phase])
414                 end
415         end,
416
417         on_punch = function(self, hitter)
418         end,
419 })
420
421 minetest.register_on_chat_message(function(name, message)
422         local cmd = "/dummyball"
423         if message:sub(0, #cmd) == cmd then
424                 if not minetest.get_player_privs(name)["give"] then
425                         minetest.chat_send_player(name, "you don't have permission to spawn (give)")
426                         return true -- Handled chat message
427                 end
428                 if not minetest.get_player_privs(name)["interact"] then
429                         minetest.chat_send_player(name, "you don't have permission to interact")
430                         return true -- Handled chat message
431                 end
432                 local player = minetest.env:get_player_by_name(name)
433                 if player == nil then
434                         print("Unable to spawn entity, player is nil")
435                         return true -- Handled chat message
436                 end
437                 local entityname = "experimental:dummyball"
438                 local p = player:getpos()
439                 p.y = p.y + 1
440                 minetest.env:add_entity(p, entityname)
441                 minetest.chat_send_player(name, '"'..entityname
442                                 ..'" spawned.');
443                 return true -- Handled chat message
444         end
445 end)
446
447 --
448 -- A test entity for testing animated and yaw-modulated sprites
449 --
450
451 minetest.register_entity("experimental:testentity", {
452         -- Static definition
453         physical = true, -- Collides with things
454         -- weight = 5,
455         collisionbox = {-0.7,-1.35,-0.7, 0.7,1.0,0.7},
456         --collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
457         visual = "sprite",
458         visual_size = {x=2, y=3},
459         textures = {"dungeon_master.png^[makealpha:128,0,0^[makealpha:128,128,0"},
460         spritediv = {x=6, y=5},
461         initial_sprite_basepos = {x=0, y=0},
462
463         on_activate = function(self, staticdata)
464                 print("testentity.on_activate")
465                 self.object:setsprite({x=0,y=0}, 1, 0, true)
466                 --self.object:setsprite({x=0,y=0}, 4, 0.3, true)
467
468                 -- Set gravity
469                 self.object:setacceleration({x=0, y=-10, z=0})
470                 -- Jump a bit upwards
471                 self.object:setvelocity({x=0, y=10, z=0})
472         end,
473
474         on_punch = function(self, hitter)
475                 self.object:remove()
476                 hitter:add_to_inventory('craft testobject1 1')
477         end,
478 })
479
480 --
481 -- More random stuff
482 --
483
484 minetest.register_on_respawnplayer(function(player)
485         print("on_respawnplayer")
486         -- player:setpos({x=0, y=30, z=0})
487         -- return true
488 end)
489
490 minetest.register_on_generated(function(minp, maxp)
491         --print("on_generated: minp="..dump(minp).." maxp="..dump(maxp))
492         --cp = {x=(minp.x+maxp.x)/2, y=(minp.y+maxp.y)/2, z=(minp.z+maxp.z)/2}
493         --minetest.env:add_node(cp, {name="sand"})
494 end)
495
496 -- Example setting get
497 --print("setting max_users = " .. dump(minetest.setting_get("max_users")))
498 --print("setting asdf = " .. dump(minetest.setting_get("asdf")))
499
500 minetest.register_on_chat_message(function(name, message)
501         --[[print("on_chat_message: name="..dump(name).." message="..dump(message))
502         local cmd = "/testcommand"
503         if message:sub(0, #cmd) == cmd then
504                 print(cmd.." invoked")
505                 return true
506         end
507         local cmd = "/help"
508         if message:sub(0, #cmd) == cmd then
509                 print("script-overridden help command")
510                 minetest.chat_send_all("script-overridden help command")
511                 return true
512         end]]
513 end)
514
515 -- Grow papyrus on TNT every 10 seconds
516 --[[minetest.register_abm({
517         nodenames = {"TNT"},
518         interval = 10.0,
519         chance = 1,
520         action = function(pos, node, active_object_count, active_object_count_wider)
521                 print("TNT ABM action")
522                 pos.y = pos.y + 1
523                 minetest.env:add_node(pos, {name="papyrus"})
524         end,
525 })]]
526
527 -- Replace texts of alls signs with "foo" every 10 seconds
528 --[[minetest.register_abm({
529         nodenames = {"sign_wall"},
530         interval = 10.0,
531         chance = 1,
532         action = function(pos, node, active_object_count, active_object_count_wider)
533                 print("ABM: Sign text changed")
534                 local meta = minetest.env:get_meta(pos)
535                 meta:set_text("foo")
536         end,
537 })]]
538
539 --[[local ncpos = nil
540 local ncq = 1
541 local ncstuff = {
542     {2, 1, 0, 3}, {3, 0, 1, 2}, {4, -1, 0, 1}, {5, -1, 0, 1}, {6, 0, -1, 0},
543     {7, 0, -1, 0}, {8, 1, 0, 3}, {9, 1, 0, 3}, {10, 1, 0, 3}, {11, 0, 1, 2},
544     {12, 0, 1, 2}, {13, 0, 1, 2}, {14, -1, 0, 1}, {15, -1, 0, 1}, {16, -1, 0, 1},
545     {17, -1, 0, 1}, {18, 0, -1, 0}, {19, 0, -1, 0}, {20, 0, -1, 0}, {21, 0, -1, 0},
546     {22, 1, 0, 3}, {23, 1, 0, 3}, {24, 1, 0, 3}, {25, 1, 0, 3}, {10, 0, 1, 2}
547 }
548 local ncold = {}
549 local nctime = nil
550
551 minetest.register_abm({
552     nodenames = {"dirt_with_grass"},
553     interval = 100000.0,
554     chance = 1,
555     action = function(pos, node, active_object_count, active_object_count_wider)
556         if ncpos ~= nil then
557             return
558         end
559        
560         if pos.x % 16 ~= 8 or pos.z % 16 ~= 8 then
561             return
562         end
563        
564         pos.y = pos.y + 1
565         n = minetest.env:get_node(pos)
566         print(dump(n))
567         if n.name ~= "air" then
568             return
569         end
570
571         pos.y = pos.y + 2
572         ncpos = pos
573         nctime = os.clock()
574         minetest.env:add_node(ncpos, {name="nyancat"})
575     end
576 })
577
578 minetest.register_abm({
579     nodenames = {"nyancat"},
580     interval = 1.0,
581     chance = 1,
582     action = function(pos, node, active_object_count, active_object_count_wider)
583         if ncpos == nil then
584             return
585         end
586         if pos.x == ncpos.x and pos.y == ncpos.y and pos.z == ncpos.z then
587             clock = os.clock()
588             if clock - nctime < 0.1 then
589                 return
590             end
591             nctime = clock
592            
593             s0 = ncstuff[ncq]
594             ncq = s0[1]
595             s1 = ncstuff[ncq]
596             p0 = pos
597             p1 = {x = p0.x + s0[2], y = p0.y, z = p0.z + s0[3]}
598             p2 = {x = p1.x + s1[2], y = p1.y, z = p1.z + s1[3]}
599             table.insert(ncold, 1, p0)
600             while #ncold >= 10 do
601                 minetest.env:add_node(ncold[#ncold], {name="air"})
602                 table.remove(ncold, #ncold)
603             end
604             minetest.env:add_node(p0, {name="nyancat_rainbow"})
605             minetest.env:add_node(p1, {name="nyancat", param1=s0[4]})
606             minetest.env:add_node(p2, {name="air"})
607             ncpos = p1
608         end
609     end,
610 })--]]
611
612 print("experimental modname="..dump(minetest.get_current_modname()))
613 print("experimental modpath="..dump(minetest.get_modpath("experimental")))
614 print("experimental worldpath="..dump(minetest.get_worldpath()))
615
616 -- END