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
.settings
:get_bool("creative_mode") 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
195 if self
._old_pos
then
196 self
.object
:set_pos(self
._old_pos
)
198 mcl_player
.player_attached
[self
._driver
] = nil
199 local player
= minetest
.get_player_by_name(self
._driver
)
202 player
:set_eye_offset({x
=0, y
=0, z
=0},{x
=0, y
=0, z
=0})
206 -- Explode if already ignited
207 if self
._boomtimer
then
209 mcl_explosions
.explode(pos
, 4, { drop_chance
= 1.0 })
213 -- Drop items and remove cart entity
214 if not minetest
.settings
:get_bool("creative_mode") then
216 minetest
.add_item(self
.object
:get_pos(), drop
[d
])
223 self
._last_float_check
= 0
226 -- Update furnace stuff
227 if self
._fueltime
and self
._fueltime
> 0 then
228 self
._fueltime
= self
._fueltime
- dtime
229 if self
._fueltime
<= 0 then
230 self
.object
:set_properties({textures
=
232 "default_furnace_top.png",
233 "default_furnace_top.png",
234 "default_furnace_front.png",
235 "default_furnace_side.png",
236 "default_furnace_side.png",
237 "default_furnace_side.png",
238 "mcl_minecarts_minecart.png",
243 local has_fuel
= self
._fueltime
and self
._fueltime
> 0
246 if self
._boomtimer
then
248 self
._boomtimer
= self
._boomtimer
- dtime
249 local pos
= self
.object
:get_pos()
250 if self
._boomtimer
<= 0 then
252 mcl_explosions
.explode(pos
, 4, { drop_chance
= 1.0 })
258 if self
._blinktimer
then
259 self
._blinktimer
= self
._blinktimer
- dtime
260 if self
._blinktimer
<= 0 then
261 self
._blink
= not self
._blink
263 self
.object
:set_properties({textures
=
265 "default_tnt_top.png",
266 "default_tnt_bottom.png",
267 "default_tnt_side.png",
268 "default_tnt_side.png",
269 "default_tnt_side.png",
270 "default_tnt_side.png",
271 "mcl_minecarts_minecart.png",
274 self
.object
:set_properties({textures
=
282 "mcl_minecarts_minecart.png",
285 self
._blinktimer
= tnt
.BLINKTIMER
289 if self
._punched
then
290 vel
= vector
.add(vel
, self
._velocity
)
291 self
.object
:set_velocity(vel
)
293 elseif vector
.equals(vel
, {x
=0, y
=0, z
=0}) and (not has_fuel
) then
297 local dir
, last_switch
= nil, nil
299 pos
= self
.object
:get_pos()
301 if self
._old_pos
and not self
._punched
then
302 local flo_pos
= vector
.floor(pos
)
303 local flo_old
= vector
.floor(self
._old_pos
)
304 if vector
.equals(flo_pos
, flo_old
) and (not has_fuel
) then
306 -- Prevent querying the same node over and over again
310 rou_pos
= vector
.round(pos
)
312 rou_old
= vector
.round(self
._old_pos
)
314 node
= minetest
.get_node(rou_pos
)
316 local node_old
= minetest
.get_node(rou_old
)
318 -- Update detector rails
319 if node
.name
== "mcl_minecarts:detector_rail" then
320 local newnode
= {name
="mcl_minecarts:detector_rail_on", param2
= node
.param2
}
321 minetest
.swap_node(rou_pos
, newnode
)
322 mesecon
.receptor_on(rou_pos
)
324 if node_old
.name
== "mcl_minecarts:detector_rail_on" then
325 local newnode
= {name
="mcl_minecarts:detector_rail", param2
= node_old
.param2
}
326 minetest
.swap_node(rou_old
, newnode
)
327 mesecon
.receptor_off(rou_old
)
329 -- Activate minecart if on activator rail
330 if node_old
.name
== "mcl_minecarts:activator_rail_on" and self
.on_activate_by_rail
then
331 self
:on_activate_by_rail()
335 local ctrl
, player
= nil, nil
337 player
= minetest
.get_player_by_name(self
._driver
)
339 ctrl
= player
:get_player_control()
343 -- Stop cart if velocity vector flips
344 if self
._old_vel
and self
._old_vel
.y
== 0 and
345 (self
._old_vel
.x
* vel
.x
< 0 or self
._old_vel
.z
* vel
.z
< 0) then
346 self
._old_vel
= {x
= 0, y
= 0, z
= 0}
348 self
.object
:set_velocity(vector
.new())
349 self
.object
:set_acceleration(vector
.new())
352 self
._old_vel
= vector
.new(vel
)
354 if self
._old_pos
then
355 local diff
= vector
.subtract(self
._old_pos
, pos
)
356 for _
,v
in ipairs({"x","y","z"}) do
357 if math
.abs(diff
[v
]) > 1.1 then
358 local expected_pos
= vector
.add(self
._old_pos
, self
._old_dir
)
359 dir
, last_switch
= mcl_minecarts
:get_rail_direction(pos
, self
._old_dir
, ctrl
, self
._old_switch
, self
._railtype
)
360 if vector
.equals(dir
, {x
=0, y
=0, z
=0}) then
362 pos
= vector
.new(expected_pos
)
371 for _
,v
in ipairs({"x", "z"}) do
372 if vel
[v
] ~= 0 and math
.abs(vel
[v
]) < 0.9 then
379 local cart_dir
= mcl_minecarts
:velocity_to_dir(vel
)
380 local max_vel
= mcl_minecarts
.speed_max
382 dir
, last_switch
= mcl_minecarts
:get_rail_direction(pos
, cart_dir
, ctrl
, self
._old_switch
, self
._railtype
)
385 local new_acc
= {x
=0, y
=0, z
=0}
386 if vector
.equals(dir
, {x
=0, y
=0, z
=0}) and not has_fuel
then
387 vel
= {x
=0, y
=0, z
=0}
390 -- If the direction changed
391 if dir
.x
~= 0 and self
._old_dir
.z
~= 0 then
392 vel
.x
= dir
.x
* math
.abs(vel
.z
)
394 pos
.z
= math
.floor(pos
.z
+ 0.5)
397 if dir
.z
~= 0 and self
._old_dir
.x
~= 0 then
398 vel
.z
= dir
.z
* math
.abs(vel
.x
)
400 pos
.x
= math
.floor(pos
.x
+ 0.5)
404 if dir
.y
~= self
._old_dir
.y
then
405 vel
.y
= dir
.y
* math
.abs(vel
.x
+ vel
.z
)
406 pos
= vector
.round(pos
)
410 -- Slow down or speed up
411 local acc
= dir
.y
* -1.8
413 local speed_mod
= minetest
.registered_nodes
[minetest
.get_node(pos
).name
]._rail_acceleration
416 elseif speed_mod
and speed_mod
~= 0 then
417 acc
= acc
+ speed_mod
422 new_acc
= vector
.multiply(dir
, acc
)
425 self
.object
:set_acceleration(new_acc
)
426 self
._old_pos
= vector
.new(pos
)
427 self
._old_dir
= vector
.new(dir
)
428 self
._old_switch
= last_switch
431 for _
,v
in ipairs({"x","y","z"}) do
432 if math
.abs(vel
[v
]) > max_vel
then
433 vel
[v
] = mcl_minecarts
:get_sign(vel
[v
]) * max_vel
439 -- Give achievement when player reached a distance of 1000 nodes from the start position
440 if self
._driver
and (vector
.distance(self
._start_pos
, pos
) >= 1000) then
441 awards
.unlock(self
._driver
, "mcl:onARail")
445 if update
.pos
or self
._punched
then
449 elseif dir
.x
> 0 then
451 elseif dir
.z
< 0 then
454 self
.object
:set_yaw(yaw
* math
.pi
)
457 if self
._punched
then
458 self
._punched
= false
461 if not (update
.vel
or update
.pos
) then
466 local anim
= {x
=0, y
=0}
469 elseif dir
.y
== 1 then
472 self
.object
:set_animation(anim
, 1, 0)
474 self
.object
:set_velocity(vel
)
476 self
.object
:set_pos(pos
)
481 function cart
:get_staticdata()
482 return minetest
.serialize({_railtype
= self
._railtype
})
485 minetest
.register_entity(entity_id
, cart
)
488 -- Place a minecart at pointed_thing
489 mcl_minecarts
.place_minecart
= function(itemstack
, pointed_thing
)
490 if not pointed_thing
.type == "node" then
495 if mcl_minecarts
:is_rail(pointed_thing
.under
) then
496 railpos
= pointed_thing
.under
497 node
= minetest
.get_node(pointed_thing
.under
)
498 elseif mcl_minecarts
:is_rail(pointed_thing
.above
) then
499 railpos
= pointed_thing
.above
500 node
= minetest
.get_node(pointed_thing
.above
)
505 -- Activate detector rail
506 if node
.name
== "mcl_minecarts:detector_rail" then
507 local newnode
= {name
="mcl_minecarts:detector_rail_on", param2
= node
.param2
}
508 minetest
.swap_node(railpos
, newnode
)
509 mesecon
.receptor_on(railpos
)
512 local entity_id
= entity_mapping
[itemstack
:get_name()]
513 local cart
= minetest
.add_entity(railpos
, entity_id
)
514 local railtype
= minetest
.get_item_group(node
.name
, "connect_to_raillike")
515 local le
= cart
:get_luaentity()
517 le
._railtype
= railtype
519 local cart_dir
= mcl_minecarts
:get_rail_direction(railpos
, {x
=1, y
=0, z
=0}, nil, nil, railtype
)
520 cart
:set_yaw(minetest
.dir_to_yaw(cart_dir
))
522 if not minetest
.settings
:get_bool("creative_mode") then
523 itemstack
:take_item()
529 local register_craftitem
= function(itemstring
, entity_id
, description
, tt_help
, longdesc
, usagehelp
, icon
, creative
)
530 entity_mapping
[itemstring
] = entity_id
532 local groups
= { minecart
= 1, transport
= 1 }
533 if creative
== false then
534 groups
.not_in_creative_inventory
= 1
538 on_place
= function(itemstack
, placer
, pointed_thing
)
539 if not pointed_thing
.type == "node" then
543 -- Call on_rightclick if the pointed node defines it
544 local node
= minetest
.get_node(pointed_thing
.under
)
545 if placer
and not placer
:get_player_control().sneak
then
546 if minetest
.registered_nodes
[node
.name
] and minetest
.registered_nodes
[node
.name
].on_rightclick
then
547 return minetest
.registered_nodes
[node
.name
].on_rightclick(pointed_thing
.under
, node
, placer
, itemstack
) or itemstack
551 return mcl_minecarts
.place_minecart(itemstack
, pointed_thing
)
553 _on_dispense
= function(stack
, pos
, droppos
, dropnode
, dropdir
)
554 -- Place minecart as entity on rail. If there's no rail, just drop it.
556 if minetest
.get_item_group(dropnode
.name
, "rail") ~= 0 then
557 -- FIXME: This places minecarts even if the spot is already occupied
558 local pointed_thing
= { under
= droppos
, above
= { x
=droppos
.x
, y
=droppos
.y
+1, z
=droppos
.z
} }
559 placed
= mcl_minecarts
.place_minecart(stack
, pointed_thing
)
561 if placed
== nil then
563 minetest
.add_item(droppos
, stack
)
568 def
.description
= description
569 def
._tt_help
= tt_help
570 def
._doc_items_longdesc
= longdesc
571 def
._doc_items_usagehelp
= usagehelp
572 def
.inventory_image
= icon
573 def
.wield_image
= icon
574 minetest
.register_craftitem(itemstring
, def
)
579 * itemstring: Itemstring of minecart item
580 * entity_id: ID of minecart entity
581 * description: Item name / description
582 * longdesc: Long help text
583 * usagehelp: Usage help text
584 * mesh: Minecart mesh
585 * textures: Minecart textures table
587 * drop: Dropped items after destroying minecart
588 * on_rightclick: Called after rightclick
589 * on_activate_by_rail: Called when above activator rail
590 * creative: If false, don't show in Creative Inventory
592 local function register_minecart(itemstring
, entity_id
, description
, tt_help
, longdesc
, usagehelp
, mesh
, textures
, icon
, drop
, on_rightclick
, on_activate_by_rail
, creative
)
593 register_entity(entity_id
, mesh
, textures
, drop
, on_rightclick
, on_activate_by_rail
)
594 register_craftitem(itemstring
, entity_id
, description
, tt_help
, longdesc
, usagehelp
, icon
, creative
)
595 if minetest
.get_modpath("doc_identifier") ~= nil then
596 doc
.sub
.identifier
.register_object(entity_id
, "craftitems", itemstring
)
602 "mcl_minecarts:minecart",
603 "mcl_minecarts:minecart",
605 S("Vehicle for fast travel on rails"),
606 S("Minecarts can be used for a quick transportion on rails.") .. "\n" ..
607 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."),
608 S("You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.") .. "\n" ..
609 S("To obtain the minecart, punch it while holding down the sneak key.") .. "\n" ..
610 S("If it moves over a powered activator rail, you'll get ejected."),
611 "mcl_minecarts_minecart.b3d",
612 {"mcl_minecarts_minecart.png"},
613 "mcl_minecarts_minecart_normal.png",
614 {"mcl_minecarts:minecart"},
615 function(self
, clicker
)
616 local name
= clicker
:get_player_name()
617 if not clicker
or not clicker
:is_player() then
620 local player_name
= clicker
:get_player_name()
621 if self
._driver
and player_name
== self
._driver
then
623 elseif not self
._driver
then
624 self
._driver
= player_name
625 self
._start_pos
= self
.object
:get_pos()
626 mcl_player
.player_attached
[player_name
] = true
627 clicker
:set_attach(self
.object
, "", {x
=0, y
=-1.75, z
=-2}, {x
=0, y
=0, z
=0})
628 mcl_player
.player_attached
[name
] = true
629 minetest
.after(0.2, function(name
)
630 local player
= minetest
.get_player_by_name(name
)
632 mcl_player
.player_set_animation(player
, "sit" , 30)
633 player
:set_eye_offset({x
=0, y
=-5.5, z
=0},{x
=0, y
=-4, z
=0})
637 end, activate_normal_minecart
640 -- Minecart with Chest
642 "mcl_minecarts:chest_minecart",
643 "mcl_minecarts:chest_minecart",
644 S("Minecart with Chest"),
646 "mcl_minecarts_minecart_chest.b3d",
647 { "mcl_chests_normal.png", "mcl_minecarts_minecart.png" },
648 "mcl_minecarts_minecart_chest.png",
649 {"mcl_minecarts:minecart", "mcl_chests:chest"},
652 -- Minecart with Furnace
654 "mcl_minecarts:furnace_minecart",
655 "mcl_minecarts:furnace_minecart",
656 S("Minecart with Furnace"),
658 S("A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel."),
659 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" ..
660 S("To obtain the minecart and furnace, punch them while holding down the sneak key."),
662 "mcl_minecarts_minecart_block.b3d",
664 "default_furnace_top.png",
665 "default_furnace_top.png",
666 "default_furnace_front.png",
667 "default_furnace_side.png",
668 "default_furnace_side.png",
669 "default_furnace_side.png",
670 "mcl_minecarts_minecart.png",
672 "mcl_minecarts_minecart_furnace.png",
673 {"mcl_minecarts:minecart", "mcl_furnaces:furnace"},
674 -- Feed furnace with coal
675 function(self
, clicker
)
676 if not clicker
or not clicker
:is_player() then
679 if not self
._fueltime
then
682 local held
= clicker
:get_wielded_item()
683 if minetest
.get_item_group(held
:get_name(), "coal") == 1 then
684 self
._fueltime
= self
._fueltime
+ 180
686 if not minetest
.settings
:get_bool("creative_mode") then
688 local index
= clicker
:get_wield_index()
689 local inv
= clicker
:get_inventory()
690 inv
:set_stack("main", index
, held
)
692 self
.object
:set_properties({textures
=
694 "default_furnace_top.png",
695 "default_furnace_top.png",
696 "default_furnace_front_active.png",
697 "default_furnace_side.png",
698 "default_furnace_side.png",
699 "default_furnace_side.png",
700 "mcl_minecarts_minecart.png",
706 -- Minecart with Command Block
708 "mcl_minecarts:command_block_minecart",
709 "mcl_minecarts:command_block_minecart",
710 S("Minecart with Command Block"),
712 "mcl_minecarts_minecart_block.b3d",
714 "jeija_commandblock_off.png^[verticalframe:2:0",
715 "jeija_commandblock_off.png^[verticalframe:2:0",
716 "jeija_commandblock_off.png^[verticalframe:2:0",
717 "jeija_commandblock_off.png^[verticalframe:2:0",
718 "jeija_commandblock_off.png^[verticalframe:2:0",
719 "jeija_commandblock_off.png^[verticalframe:2:0",
720 "mcl_minecarts_minecart.png",
722 "mcl_minecarts_minecart_command_block.png",
723 {"mcl_minecarts:minecart"},
727 -- Minecart with Hopper
729 "mcl_minecarts:hopper_minecart",
730 "mcl_minecarts:hopper_minecart",
731 S("Minecart with Hopper"),
733 "mcl_minecarts_minecart_hopper.b3d",
735 "mcl_hoppers_hopper_inside.png",
736 "mcl_minecarts_minecart.png",
737 "mcl_hoppers_hopper_outside.png",
738 "mcl_hoppers_hopper_top.png",
740 "mcl_minecarts_minecart_hopper.png",
741 {"mcl_minecarts:minecart", "mcl_hoppers:hopper"},
747 "mcl_minecarts:tnt_minecart",
748 "mcl_minecarts:tnt_minecart",
749 S("Minecart with TNT"),
750 S("Vehicle for fast travel on rails").."\n"..S("Can be ignited by tools or powered activator rail"),
751 S("A minecart with TNT is an explosive vehicle that travels on rail."),
752 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" ..
753 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."),
754 "mcl_minecarts_minecart_block.b3d",
756 "default_tnt_top.png",
757 "default_tnt_bottom.png",
758 "default_tnt_side.png",
759 "default_tnt_side.png",
760 "default_tnt_side.png",
761 "default_tnt_side.png",
762 "mcl_minecarts_minecart.png",
764 "mcl_minecarts_minecart_tnt.png",
765 {"mcl_minecarts:minecart", "mcl_tnt:tnt"},
767 function(self
, clicker
)
768 if not clicker
or not clicker
:is_player() then
771 if self
._boomtimer
then
774 local held
= clicker
:get_wielded_item()
775 if held
:get_name() == "mcl_fire:flint_and_steel" then
776 if not minetest
.settings
:get_bool("creative_mode") then
777 held
:add_wear(65535/65) -- 65 uses
778 local index
= clicker
:get_wield_index()
779 local inv
= clicker
:get_inventory()
780 inv
:set_stack("main", index
, held
)
782 activate_tnt_minecart(self
)
784 end, activate_tnt_minecart
)
787 minetest
.register_craft({
788 output
= "mcl_minecarts:minecart",
790 {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"},
791 {"mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot"},
795 minetest
.register_craft({
796 output
= "mcl_minecarts:tnt_minecart",
799 {"mcl_minecarts:minecart"},
803 -- TODO: Re-enable crafting of special minecarts when they have been implemented
806 minetest
.register_craft({
807 output
= "mcl_minecarts:furnace_minecart",
809 {"mcl_furnaces:furnace"},
810 {"mcl_minecarts:minecart"},
814 minetest
.register_craft({
815 output
= "mcl_minecarts:hopper_minecart",
817 {"mcl_hoppers:hopper"},
818 {"mcl_minecarts:minecart"},
822 minetest
.register_craft({
823 output
= "mcl_minecarts:chest_minecart",
825 {"mcl_chests:chest"},
826 {"mcl_minecarts:minecart"},