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