1 local S
= minetest
.get_translator("mcl_minecarts")
4 mcl_minecarts
.modpath
= minetest
.get_modpath("mcl_minecarts")
5 mcl_minecarts
.speed_max
= 10
6 mcl_minecarts
.check_float_time
= 15
8 dofile(mcl_minecarts
.modpath
.."/functions.lua")
9 dofile(mcl_minecarts
.modpath
.."/rails.lua")
11 local function detach_driver(self
)
12 if not self
._driver
then
15 mcl_player
.player_attached
[self
._driver
] = nil
16 local player
= minetest
.get_player_by_name(self
._driver
)
21 player
:set_eye_offset({x
=0, y
=0, z
=0},{x
=0, y
=0, z
=0})
22 mcl_player
.player_set_animation(player
, "stand" , 30)
26 local function activate_tnt_minecart(self
, timer
)
27 if self
._boomtimer
then
30 self
.object
:set_armor_groups({immortal
=1})
32 self
._boomtimer
= timer
34 self
._boomtimer
= tnt
.BOOMTIMER
36 self
.object
:set_properties({textures
= {
43 "mcl_minecarts_minecart.png",
45 self
._blinktimer
= tnt
.BLINKTIMER
46 minetest
.sound_play("tnt_ignite", {pos
= self
.object
:get_pos(), gain
= 1.0, max_hear_distance
= 15}, true)
49 local activate_normal_minecart
= detach_driver
51 -- Table for item-to-entity mapping. Keys: itemstring, Values: Corresponding entity ID
52 local entity_mapping
= {}
54 local function register_entity(entity_id
, mesh
, textures
, drop
, on_rightclick
, on_activate_by_rail
)
57 collisionbox
= {-10/16., -0.5, -10/16, 10/16, 0.25, 10/16},
60 visual_size
= {x
=1, y
=1},
63 on_rightclick
= on_rightclick
,
65 _driver
= nil, -- player who sits in and controls the minecart (only for minecart!)
66 _punched
= false, -- used to re-send _velocity and position
67 _velocity
= {x
=0, y
=0, z
=0}, -- only used on punch
68 _start_pos
= nil, -- Used to calculate distance for “On A Rail” achievement
69 _last_float_check
= nil, -- timestamp of last time the cart was checked to be still on a rail
70 _fueltime
= nil, -- how many seconds worth of fuel is left. Only used by minecart with furnace
71 _boomtimer
= nil, -- how many seconds are left before exploding
72 _blinktimer
= nil, -- how many seconds are left before TNT blinking
73 _blink
= false, -- is TNT blink texture active?
74 _old_dir
= {x
=0, y
=0, z
=0},
76 _old_vel
= {x
=0, y
=0, z
=0},
81 function cart
:on_activate(staticdata
, dtime_s
)
83 local data
= minetest
.deserialize(staticdata
)
84 if type(data
) == "table" then
85 self
._railtype
= data
._railtype
87 self
.object
:set_armor_groups({immortal
=1})
89 -- Activate cart if on activator rail
90 if self
.on_activate_by_rail
then
91 local pos
= self
.object
:get_pos()
92 local node
= minetest
.get_node(vector
.floor(pos
))
93 if node
.name
== "mcl_minecarts:activator_rail_on" then
94 self
:on_activate_by_rail()
99 function cart
:on_punch(puncher
, time_from_last_punch
, tool_capabilities
, direction
)
100 local pos
= self
.object
:get_pos()
101 if not self
._railtype
then
102 local node
= minetest
.get_node(vector
.floor(pos
)).name
103 self
._railtype
= minetest
.get_item_group(node
, "connect_to_raillike")
106 if not puncher
or not puncher
:is_player() then
107 local cart_dir
= mcl_minecarts
:get_rail_direction(pos
, {x
=1, y
=0, z
=0}, nil, nil, self
._railtype
)
108 if vector
.equals(cart_dir
, {x
=0, y
=0, z
=0}) then
111 self
._velocity
= vector
.multiply(cart_dir
, 3)
117 -- Punch+sneak: Pick up minecart (unless TNT was ignited)
118 if puncher
:get_player_control().sneak
and not self
._boomtimer
then
120 if self
._old_pos
then
121 self
.object
:set_pos(self
._old_pos
)
126 -- Disable detector rail
127 local rou_pos
= vector
.round(pos
)
128 local node
= minetest
.get_node(rou_pos
)
129 if node
.name
== "mcl_minecarts:detector_rail_on" then
130 local newnode
= {name
="mcl_minecarts:detector_rail", param2
= node
.param2
}
131 minetest
.swap_node(rou_pos
, newnode
)
132 mesecon
.receptor_off(rou_pos
)
135 -- Drop items and remove cart entity
136 if not minetest
.is_creative_enabled(puncher
:get_player_name()) then
138 minetest
.add_item(self
.object
:get_pos(), drop
[d
])
140 elseif puncher
and puncher
:is_player() then
141 local inv
= puncher
:get_inventory()
143 if not inv
:contains_item("main", drop
[d
]) then
144 inv
:add_item("main", drop
[d
])
153 local vel
= self
.object
:get_velocity()
154 if puncher
:get_player_name() == self
._driver
then
155 if math
.abs(vel
.x
+ vel
.z
) > 7 then
160 local punch_dir
= mcl_minecarts
:velocity_to_dir(puncher
:get_look_dir())
162 local cart_dir
= mcl_minecarts
:get_rail_direction(pos
, punch_dir
, nil, nil, self
._railtype
)
163 if vector
.equals(cart_dir
, {x
=0, y
=0, z
=0}) then
167 time_from_last_punch
= math
.min(time_from_last_punch
, tool_capabilities
.full_punch_interval
)
168 local f
= 3 * (time_from_last_punch
/ tool_capabilities
.full_punch_interval
)
170 self
._velocity
= vector
.multiply(cart_dir
, f
)
175 cart
.on_activate_by_rail
= on_activate_by_rail
177 function cart
:on_step(dtime
)
178 local vel
= self
.object
:get_velocity()
180 if self
._last_float_check
== nil then
181 self
._last_float_check
= 0
183 self
._last_float_check
= self
._last_float_check
+ dtime
185 local pos
, rou_pos
, node
186 -- Drop minecart if it isn't on a rail anymore
187 if self
._last_float_check
>= mcl_minecarts
.check_float_time
then
188 pos
= self
.object
:get_pos()
189 rou_pos
= vector
.round(pos
)
190 node
= minetest
.get_node(rou_pos
)
191 local g
= minetest
.get_item_group(node
.name
, "connect_to_raillike")
192 if g
~= self
._railtype
and self
._railtype
~= nil then
196 if self
._old_pos
then
197 self
.object
:set_pos(self
._old_pos
)
199 mcl_player
.player_attached
[self
._driver
] = nil
200 player
= minetest
.get_player_by_name(self
._driver
)
203 player
:set_eye_offset({x
=0, y
=0, z
=0},{x
=0, y
=0, z
=0})
207 -- Explode if already ignited
208 if self
._boomtimer
then
210 mcl_explosions
.explode(pos
, 4, { drop_chance
= 1.0 })
214 -- Drop items and remove cart entity
217 pname
= player
:get_player_name()
219 if not minetest
.is_creative_enabled(pname
) then
221 minetest
.add_item(self
.object
:get_pos(), drop
[d
])
228 self
._last_float_check
= 0
231 -- Update furnace stuff
232 if self
._fueltime
and self
._fueltime
> 0 then
233 self
._fueltime
= self
._fueltime
- dtime
234 if self
._fueltime
<= 0 then
235 self
.object
:set_properties({textures
=
237 "default_furnace_top.png",
238 "default_furnace_top.png",
239 "default_furnace_front.png",
240 "default_furnace_side.png",
241 "default_furnace_side.png",
242 "default_furnace_side.png",
243 "mcl_minecarts_minecart.png",
248 local has_fuel
= self
._fueltime
and self
._fueltime
> 0
251 if self
._boomtimer
then
253 self
._boomtimer
= self
._boomtimer
- dtime
254 local pos
= self
.object
:get_pos()
255 if self
._boomtimer
<= 0 then
257 mcl_explosions
.explode(pos
, 4, { drop_chance
= 1.0 })
263 if self
._blinktimer
then
264 self
._blinktimer
= self
._blinktimer
- dtime
265 if self
._blinktimer
<= 0 then
266 self
._blink
= not self
._blink
268 self
.object
:set_properties({textures
=
270 "default_tnt_top.png",
271 "default_tnt_bottom.png",
272 "default_tnt_side.png",
273 "default_tnt_side.png",
274 "default_tnt_side.png",
275 "default_tnt_side.png",
276 "mcl_minecarts_minecart.png",
279 self
.object
:set_properties({textures
=
287 "mcl_minecarts_minecart.png",
290 self
._blinktimer
= tnt
.BLINKTIMER
294 if self
._punched
then
295 vel
= vector
.add(vel
, self
._velocity
)
296 self
.object
:set_velocity(vel
)
298 elseif vector
.equals(vel
, {x
=0, y
=0, z
=0}) and (not has_fuel
) then
302 local dir
, last_switch
= nil, nil
304 pos
= self
.object
:get_pos()
306 if self
._old_pos
and not self
._punched
then
307 local flo_pos
= vector
.floor(pos
)
308 local flo_old
= vector
.floor(self
._old_pos
)
309 if vector
.equals(flo_pos
, flo_old
) and (not has_fuel
) then
311 -- Prevent querying the same node over and over again
315 rou_pos
= vector
.round(pos
)
317 local rou_old
= vector
.round(self
._old_pos
)
319 node
= minetest
.get_node(rou_pos
)
321 local node_old
= minetest
.get_node(rou_old
)
323 -- Update detector rails
324 if node
.name
== "mcl_minecarts:detector_rail" then
325 local newnode
= {name
="mcl_minecarts:detector_rail_on", param2
= node
.param2
}
326 minetest
.swap_node(rou_pos
, newnode
)
327 mesecon
.receptor_on(rou_pos
)
329 if node_old
.name
== "mcl_minecarts:detector_rail_on" then
330 local newnode
= {name
="mcl_minecarts:detector_rail", param2
= node_old
.param2
}
331 minetest
.swap_node(rou_old
, newnode
)
332 mesecon
.receptor_off(rou_old
)
334 -- Activate minecart if on activator rail
335 if node_old
.name
== "mcl_minecarts:activator_rail_on" and self
.on_activate_by_rail
then
336 self
:on_activate_by_rail()
340 local ctrl
, player
= nil, nil
342 player
= minetest
.get_player_by_name(self
._driver
)
344 ctrl
= player
:get_player_control()
348 -- Stop cart if velocity vector flips
349 if self
._old_vel
and self
._old_vel
.y
== 0 and
350 (self
._old_vel
.x
* vel
.x
< 0 or self
._old_vel
.z
* vel
.z
< 0) then
351 self
._old_vel
= {x
= 0, y
= 0, z
= 0}
353 self
.object
:set_velocity(vector
.new())
354 self
.object
:set_acceleration(vector
.new())
357 self
._old_vel
= vector
.new(vel
)
359 if self
._old_pos
then
360 local diff
= vector
.subtract(self
._old_pos
, pos
)
361 for _
,v
in ipairs({"x","y","z"}) do
362 if math
.abs(diff
[v
]) > 1.1 then
363 local expected_pos
= vector
.add(self
._old_pos
, self
._old_dir
)
364 dir
, last_switch
= mcl_minecarts
:get_rail_direction(pos
, self
._old_dir
, ctrl
, self
._old_switch
, self
._railtype
)
365 if vector
.equals(dir
, {x
=0, y
=0, z
=0}) then
367 pos
= vector
.new(expected_pos
)
376 for _
,v
in ipairs({"x", "z"}) do
377 if vel
[v
] ~= 0 and math
.abs(vel
[v
]) < 0.9 then
384 local cart_dir
= mcl_minecarts
:velocity_to_dir(vel
)
385 local max_vel
= mcl_minecarts
.speed_max
387 dir
, last_switch
= mcl_minecarts
:get_rail_direction(pos
, cart_dir
, ctrl
, self
._old_switch
, self
._railtype
)
390 local new_acc
= {x
=0, y
=0, z
=0}
391 if vector
.equals(dir
, {x
=0, y
=0, z
=0}) and not has_fuel
then
392 vel
= {x
=0, y
=0, z
=0}
395 -- If the direction changed
396 if dir
.x
~= 0 and self
._old_dir
.z
~= 0 then
397 vel
.x
= dir
.x
* math
.abs(vel
.z
)
399 pos
.z
= math
.floor(pos
.z
+ 0.5)
402 if dir
.z
~= 0 and self
._old_dir
.x
~= 0 then
403 vel
.z
= dir
.z
* math
.abs(vel
.x
)
405 pos
.x
= math
.floor(pos
.x
+ 0.5)
409 if dir
.y
~= self
._old_dir
.y
then
410 vel
.y
= dir
.y
* math
.abs(vel
.x
+ vel
.z
)
411 pos
= vector
.round(pos
)
415 -- Slow down or speed up
416 local acc
= dir
.y
* -1.8
418 local speed_mod
= minetest
.registered_nodes
[minetest
.get_node(pos
).name
]._rail_acceleration
421 elseif speed_mod
and speed_mod
~= 0 then
422 acc
= acc
+ speed_mod
427 new_acc
= vector
.multiply(dir
, acc
)
430 self
.object
:set_acceleration(new_acc
)
431 self
._old_pos
= vector
.new(pos
)
432 self
._old_dir
= vector
.new(dir
)
433 self
._old_switch
= last_switch
436 for _
,v
in ipairs({"x","y","z"}) do
437 if math
.abs(vel
[v
]) > max_vel
then
438 vel
[v
] = mcl_minecarts
:get_sign(vel
[v
]) * max_vel
444 -- Give achievement when player reached a distance of 1000 nodes from the start position
445 if self
._driver
and (vector
.distance(self
._start_pos
, pos
) >= 1000) then
446 awards
.unlock(self
._driver
, "mcl:onARail")
450 if update
.pos
or self
._punched
then
454 elseif dir
.x
> 0 then
456 elseif dir
.z
< 0 then
459 self
.object
:set_yaw(yaw
* math
.pi
)
462 if self
._punched
then
463 self
._punched
= false
466 if not (update
.vel
or update
.pos
) then
471 local anim
= {x
=0, y
=0}
474 elseif dir
.y
== 1 then
477 self
.object
:set_animation(anim
, 1, 0)
479 self
.object
:set_velocity(vel
)
481 self
.object
:set_pos(pos
)
486 function cart
:get_staticdata()
487 return minetest
.serialize({_railtype
= self
._railtype
})
490 minetest
.register_entity(entity_id
, cart
)
493 -- Place a minecart at pointed_thing
494 mcl_minecarts
.place_minecart
= function(itemstack
, pointed_thing
, placer
)
495 if not pointed_thing
.type == "node" then
500 if mcl_minecarts
:is_rail(pointed_thing
.under
) then
501 railpos
= pointed_thing
.under
502 node
= minetest
.get_node(pointed_thing
.under
)
503 elseif mcl_minecarts
:is_rail(pointed_thing
.above
) then
504 railpos
= pointed_thing
.above
505 node
= minetest
.get_node(pointed_thing
.above
)
510 -- Activate detector rail
511 if node
.name
== "mcl_minecarts:detector_rail" then
512 local newnode
= {name
="mcl_minecarts:detector_rail_on", param2
= node
.param2
}
513 minetest
.swap_node(railpos
, newnode
)
514 mesecon
.receptor_on(railpos
)
517 local entity_id
= entity_mapping
[itemstack
:get_name()]
518 local cart
= minetest
.add_entity(railpos
, entity_id
)
519 local railtype
= minetest
.get_item_group(node
.name
, "connect_to_raillike")
520 local le
= cart
:get_luaentity()
522 le
._railtype
= railtype
524 local cart_dir
= mcl_minecarts
:get_rail_direction(railpos
, {x
=1, y
=0, z
=0}, nil, nil, railtype
)
525 cart
:set_yaw(minetest
.dir_to_yaw(cart_dir
))
529 pname
= placer
:get_player_name()
531 if not minetest
.is_creative_enabled(pname
) then
532 itemstack
:take_item()
538 local register_craftitem
= function(itemstring
, entity_id
, description
, tt_help
, longdesc
, usagehelp
, icon
, creative
)
539 entity_mapping
[itemstring
] = entity_id
541 local groups
= { minecart
= 1, transport
= 1 }
542 if creative
== false then
543 groups
.not_in_creative_inventory
= 1
547 on_place
= function(itemstack
, placer
, pointed_thing
)
548 if not pointed_thing
.type == "node" then
552 -- Call on_rightclick if the pointed node defines it
553 local node
= minetest
.get_node(pointed_thing
.under
)
554 if placer
and not placer
:get_player_control().sneak
then
555 if minetest
.registered_nodes
[node
.name
] and minetest
.registered_nodes
[node
.name
].on_rightclick
then
556 return minetest
.registered_nodes
[node
.name
].on_rightclick(pointed_thing
.under
, node
, placer
, itemstack
) or itemstack
560 return mcl_minecarts
.place_minecart(itemstack
, pointed_thing
, placer
)
562 _on_dispense
= function(stack
, pos
, droppos
, dropnode
, dropdir
)
563 -- Place minecart as entity on rail. If there's no rail, just drop it.
565 if minetest
.get_item_group(dropnode
.name
, "rail") ~= 0 then
566 -- FIXME: This places minecarts even if the spot is already occupied
567 local pointed_thing
= { under
= droppos
, above
= { x
=droppos
.x
, y
=droppos
.y
+1, z
=droppos
.z
} }
568 placed
= mcl_minecarts
.place_minecart(stack
, pointed_thing
)
570 if placed
== nil then
572 minetest
.add_item(droppos
, stack
)
577 def
.description
= description
578 def
._tt_help
= tt_help
579 def
._doc_items_longdesc
= longdesc
580 def
._doc_items_usagehelp
= usagehelp
581 def
.inventory_image
= icon
582 def
.wield_image
= icon
583 minetest
.register_craftitem(itemstring
, def
)
588 * itemstring: Itemstring of minecart item
589 * entity_id: ID of minecart entity
590 * description: Item name / description
591 * longdesc: Long help text
592 * usagehelp: Usage help text
593 * mesh: Minecart mesh
594 * textures: Minecart textures table
596 * drop: Dropped items after destroying minecart
597 * on_rightclick: Called after rightclick
598 * on_activate_by_rail: Called when above activator rail
599 * creative: If false, don't show in Creative Inventory
601 local function register_minecart(itemstring
, entity_id
, description
, tt_help
, longdesc
, usagehelp
, mesh
, textures
, icon
, drop
, on_rightclick
, on_activate_by_rail
, creative
)
602 register_entity(entity_id
, mesh
, textures
, drop
, on_rightclick
, on_activate_by_rail
)
603 register_craftitem(itemstring
, entity_id
, description
, tt_help
, longdesc
, usagehelp
, icon
, creative
)
604 if minetest
.get_modpath("doc_identifier") ~= nil then
605 doc
.sub
.identifier
.register_object(entity_id
, "craftitems", itemstring
)
611 "mcl_minecarts:minecart",
612 "mcl_minecarts:minecart",
614 S("Vehicle for fast travel on rails"),
615 S("Minecarts can be used for a quick transportion on rails.") .. "\n" ..
616 S("Minecarts only ride on rails and always follow the tracks. At a T-junction with no straight way ahead, they turn left. The speed is affected by the rail type."),
617 S("You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.") .. "\n" ..
618 S("To obtain the minecart, punch it while holding down the sneak key.") .. "\n" ..
619 S("If it moves over a powered activator rail, you'll get ejected."),
620 "mcl_minecarts_minecart.b3d",
621 {"mcl_minecarts_minecart.png"},
622 "mcl_minecarts_minecart_normal.png",
623 {"mcl_minecarts:minecart"},
624 function(self
, clicker
)
625 local name
= clicker
:get_player_name()
626 if not clicker
or not clicker
:is_player() then
629 local player_name
= clicker
:get_player_name()
630 if self
._driver
and player_name
== self
._driver
then
632 elseif not self
._driver
then
633 self
._driver
= player_name
634 self
._start_pos
= self
.object
:get_pos()
635 mcl_player
.player_attached
[player_name
] = true
636 clicker
:set_attach(self
.object
, "", {x
=0, y
=-1.75, z
=-2}, {x
=0, y
=0, z
=0})
637 mcl_player
.player_attached
[name
] = true
638 minetest
.after(0.2, function(name
)
639 local player
= minetest
.get_player_by_name(name
)
641 mcl_player
.player_set_animation(player
, "sit" , 30)
642 player
:set_eye_offset({x
=0, y
=-5.5, z
=0},{x
=0, y
=-4, z
=0})
646 end, activate_normal_minecart
649 -- Minecart with Chest
651 "mcl_minecarts:chest_minecart",
652 "mcl_minecarts:chest_minecart",
653 S("Minecart with Chest"),
655 "mcl_minecarts_minecart_chest.b3d",
656 { "mcl_chests_normal.png", "mcl_minecarts_minecart.png" },
657 "mcl_minecarts_minecart_chest.png",
658 {"mcl_minecarts:minecart", "mcl_chests:chest"},
661 -- Minecart with Furnace
663 "mcl_minecarts:furnace_minecart",
664 "mcl_minecarts:furnace_minecart",
665 S("Minecart with Furnace"),
667 S("A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel."),
668 S("Place it on rails. If you give it some coal, the furnace will start burning for a long time and the minecart will be able to move itself. Punch it to get it moving.") .. "\n" ..
669 S("To obtain the minecart and furnace, punch them while holding down the sneak key."),
671 "mcl_minecarts_minecart_block.b3d",
673 "default_furnace_top.png",
674 "default_furnace_top.png",
675 "default_furnace_front.png",
676 "default_furnace_side.png",
677 "default_furnace_side.png",
678 "default_furnace_side.png",
679 "mcl_minecarts_minecart.png",
681 "mcl_minecarts_minecart_furnace.png",
682 {"mcl_minecarts:minecart", "mcl_furnaces:furnace"},
683 -- Feed furnace with coal
684 function(self
, clicker
)
685 if not clicker
or not clicker
:is_player() then
688 if not self
._fueltime
then
691 local held
= clicker
:get_wielded_item()
692 if minetest
.get_item_group(held
:get_name(), "coal") == 1 then
693 self
._fueltime
= self
._fueltime
+ 180
695 if not minetest
.is_creative_enabled(clicker
:get_player_name()) then
697 local index
= clicker
:get_wield_index()
698 local inv
= clicker
:get_inventory()
699 inv
:set_stack("main", index
, held
)
701 self
.object
:set_properties({textures
=
703 "default_furnace_top.png",
704 "default_furnace_top.png",
705 "default_furnace_front_active.png",
706 "default_furnace_side.png",
707 "default_furnace_side.png",
708 "default_furnace_side.png",
709 "mcl_minecarts_minecart.png",
715 -- Minecart with Command Block
717 "mcl_minecarts:command_block_minecart",
718 "mcl_minecarts:command_block_minecart",
719 S("Minecart with Command Block"),
721 "mcl_minecarts_minecart_block.b3d",
723 "jeija_commandblock_off.png^[verticalframe:2:0",
724 "jeija_commandblock_off.png^[verticalframe:2:0",
725 "jeija_commandblock_off.png^[verticalframe:2:0",
726 "jeija_commandblock_off.png^[verticalframe:2:0",
727 "jeija_commandblock_off.png^[verticalframe:2:0",
728 "jeija_commandblock_off.png^[verticalframe:2:0",
729 "mcl_minecarts_minecart.png",
731 "mcl_minecarts_minecart_command_block.png",
732 {"mcl_minecarts:minecart"},
736 -- Minecart with Hopper
738 "mcl_minecarts:hopper_minecart",
739 "mcl_minecarts:hopper_minecart",
740 S("Minecart with Hopper"),
742 "mcl_minecarts_minecart_hopper.b3d",
744 "mcl_hoppers_hopper_inside.png",
745 "mcl_minecarts_minecart.png",
746 "mcl_hoppers_hopper_outside.png",
747 "mcl_hoppers_hopper_top.png",
749 "mcl_minecarts_minecart_hopper.png",
750 {"mcl_minecarts:minecart", "mcl_hoppers:hopper"},
756 "mcl_minecarts:tnt_minecart",
757 "mcl_minecarts:tnt_minecart",
758 S("Minecart with TNT"),
759 S("Vehicle for fast travel on rails").."\n"..S("Can be ignited by tools or powered activator rail"),
760 S("A minecart with TNT is an explosive vehicle that travels on rail."),
761 S("Place it on rails. Punch it to move it. The TNT is ignited with a flint and steel or when the minecart is on an powered activator rail.") .. "\n" ..
762 S("To obtain the minecart and TNT, punch them while holding down the sneak key. You can't do this if the TNT was ignited."),
763 "mcl_minecarts_minecart_block.b3d",
765 "default_tnt_top.png",
766 "default_tnt_bottom.png",
767 "default_tnt_side.png",
768 "default_tnt_side.png",
769 "default_tnt_side.png",
770 "default_tnt_side.png",
771 "mcl_minecarts_minecart.png",
773 "mcl_minecarts_minecart_tnt.png",
774 {"mcl_minecarts:minecart", "mcl_tnt:tnt"},
776 function(self
, clicker
)
777 if not clicker
or not clicker
:is_player() then
780 if self
._boomtimer
then
783 local held
= clicker
:get_wielded_item()
784 if held
:get_name() == "mcl_fire:flint_and_steel" then
785 if not minetest
.is_creative_enabled(clicker
:get_player_name()) then
786 held
:add_wear(65535/65) -- 65 uses
787 local index
= clicker
:get_wield_index()
788 local inv
= clicker
:get_inventory()
789 inv
:set_stack("main", index
, held
)
791 activate_tnt_minecart(self
)
793 end, activate_tnt_minecart
)
796 minetest
.register_craft({
797 output
= "mcl_minecarts:minecart",
799 {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"},
800 {"mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot"},
804 minetest
.register_craft({
805 output
= "mcl_minecarts:tnt_minecart",
808 {"mcl_minecarts:minecart"},
812 -- TODO: Re-enable crafting of special minecarts when they have been implemented
815 minetest
.register_craft({
816 output
= "mcl_minecarts:furnace_minecart",
818 {"mcl_furnaces:furnace"},
819 {"mcl_minecarts:minecart"},
823 minetest
.register_craft({
824 output
= "mcl_minecarts:hopper_minecart",
826 {"mcl_hoppers:hopper"},
827 {"mcl_minecarts:minecart"},
831 minetest
.register_craft({
832 output
= "mcl_minecarts:chest_minecart",
834 {"mcl_chests:chest"},
835 {"mcl_minecarts:minecart"},