Implement TNT minecart
parent
74b79d130b
commit
9dc9c12f29
|
@ -8,10 +8,29 @@ mcl_minecarts.check_float_time = 15
|
||||||
dofile(mcl_minecarts.modpath.."/functions.lua")
|
dofile(mcl_minecarts.modpath.."/functions.lua")
|
||||||
dofile(mcl_minecarts.modpath.."/rails.lua")
|
dofile(mcl_minecarts.modpath.."/rails.lua")
|
||||||
|
|
||||||
|
local function activate_tnt_minecart(self)
|
||||||
|
if self._boomtimer then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self.object:set_armor_groups({immortal=1})
|
||||||
|
self._boomtimer = tnt.BOOMTIMER
|
||||||
|
self.object:set_properties({textures = {
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_minecarts_minecart.png",
|
||||||
|
}})
|
||||||
|
self._blinktimer = tnt.BLINKTIMER
|
||||||
|
minetest.sound_play("tnt_ignite", {pos = self.object:get_pos(), gain = 1.0, max_hear_distance = 15})
|
||||||
|
end
|
||||||
|
|
||||||
-- Table for item-to-entity mapping. Keys: itemstring, Values: Corresponding entity ID
|
-- Table for item-to-entity mapping. Keys: itemstring, Values: Corresponding entity ID
|
||||||
local entity_mapping = {}
|
local entity_mapping = {}
|
||||||
|
|
||||||
local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
local function register_entity(entity_id, mesh, textures, drop, on_rightclick, on_activate_by_rail)
|
||||||
local cart = {
|
local cart = {
|
||||||
physical = false,
|
physical = false,
|
||||||
collisionbox = {-10/16., -0.5, -10/16, 10/16, 0.25, 10/16},
|
collisionbox = {-10/16., -0.5, -10/16, 10/16, 0.25, 10/16},
|
||||||
|
@ -28,6 +47,9 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
||||||
_start_pos = nil, -- Used to calculate distance for “On A Rail” achievement
|
_start_pos = nil, -- Used to calculate distance for “On A Rail” achievement
|
||||||
_last_float_check = nil, -- timestamp of last time the cart was checked to be still on a rail
|
_last_float_check = nil, -- timestamp of last time the cart was checked to be still on a rail
|
||||||
_fueltime = nil, -- how many seconds worth of fuel is left. Only used by minecart with furnace
|
_fueltime = nil, -- how many seconds worth of fuel is left. Only used by minecart with furnace
|
||||||
|
_boomtimer = nil, -- how many seconds are left before exploding
|
||||||
|
_blinktimer = nil, -- how many seconds are left before TNT blinking
|
||||||
|
_blink = false, -- is TNT blink texture active?
|
||||||
_old_dir = {x=0, y=0, z=0},
|
_old_dir = {x=0, y=0, z=0},
|
||||||
_old_pos = nil,
|
_old_pos = nil,
|
||||||
_old_vel = {x=0, y=0, z=0},
|
_old_vel = {x=0, y=0, z=0},
|
||||||
|
@ -36,11 +58,21 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
||||||
}
|
}
|
||||||
|
|
||||||
function cart:on_activate(staticdata, dtime_s)
|
function cart:on_activate(staticdata, dtime_s)
|
||||||
|
-- Initialize
|
||||||
local data = minetest.deserialize(staticdata)
|
local data = minetest.deserialize(staticdata)
|
||||||
if type(data) == "table" then
|
if type(data) == "table" then
|
||||||
self._railtype = data._railtype
|
self._railtype = data._railtype
|
||||||
end
|
end
|
||||||
self.object:set_armor_groups({immortal=1})
|
self.object:set_armor_groups({immortal=1})
|
||||||
|
|
||||||
|
-- Activate cart if on activator rail
|
||||||
|
if self.on_activate_by_rail then
|
||||||
|
local pos = self.object:get_pos()
|
||||||
|
local node = minetest.get_node(vector.floor(pos))
|
||||||
|
if node.name == "mcl_minecarts:activator_rail_on" then
|
||||||
|
self:on_activate_by_rail()
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
||||||
|
@ -61,7 +93,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if puncher:get_player_control().sneak then
|
-- Punch+sneak: Pick up minecart (unless TNT was ignited)
|
||||||
|
if puncher:get_player_control().sneak and not self._boomtimer then
|
||||||
if self._driver then
|
if self._driver then
|
||||||
if self._old_pos then
|
if self._old_pos then
|
||||||
self.object:set_pos(self._old_pos)
|
self.object:set_pos(self._old_pos)
|
||||||
|
@ -123,6 +156,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
||||||
self._punched = true
|
self._punched = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
cart.on_activate_by_rail = on_activate_by_rail
|
||||||
|
|
||||||
function cart:on_step(dtime)
|
function cart:on_step(dtime)
|
||||||
local vel = self.object:get_velocity()
|
local vel = self.object:get_velocity()
|
||||||
local update = {}
|
local update = {}
|
||||||
|
@ -152,8 +187,15 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Explode if already ignited
|
||||||
|
if self._boomtimer then
|
||||||
|
self.object:remove()
|
||||||
|
tnt.boom(pos)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- Drop items and remove cart entity
|
-- Drop items and remove cart entity
|
||||||
if not minetest.settings:get_bool("creative_mode") then
|
if not minetest.settings:get_bool("creative_mode") then
|
||||||
for d=1, #drop do
|
for d=1, #drop do
|
||||||
minetest.add_item(self.object:get_pos(), drop[d])
|
minetest.add_item(self.object:get_pos(), drop[d])
|
||||||
end
|
end
|
||||||
|
@ -165,7 +207,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
||||||
self._last_float_check = 0
|
self._last_float_check = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Update furnace texture if out of fuel
|
-- Update furnace stuff
|
||||||
if self._fueltime and self._fueltime > 0 then
|
if self._fueltime and self._fueltime > 0 then
|
||||||
self._fueltime = self._fueltime - dtime
|
self._fueltime = self._fueltime - dtime
|
||||||
if self._fueltime <= 0 then
|
if self._fueltime <= 0 then
|
||||||
|
@ -184,6 +226,50 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
||||||
end
|
end
|
||||||
local has_fuel = self._fueltime and self._fueltime > 0
|
local has_fuel = self._fueltime and self._fueltime > 0
|
||||||
|
|
||||||
|
-- Update TNT stuff
|
||||||
|
if self._boomtimer then
|
||||||
|
-- Explode
|
||||||
|
self._boomtimer = self._boomtimer - dtime
|
||||||
|
local pos = self.object:get_pos()
|
||||||
|
if self._boomtimer <= 0 then
|
||||||
|
self.object:remove()
|
||||||
|
tnt.boom(pos)
|
||||||
|
return
|
||||||
|
else
|
||||||
|
tnt.smoke_step(pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if self._blinktimer then
|
||||||
|
self._blinktimer = self._blinktimer - dtime
|
||||||
|
if self._blinktimer <= 0 then
|
||||||
|
self._blink = not self._blink
|
||||||
|
if self._blink then
|
||||||
|
self.object:set_properties({textures =
|
||||||
|
{
|
||||||
|
"default_tnt_top.png",
|
||||||
|
"default_tnt_bottom.png",
|
||||||
|
"default_tnt_side.png",
|
||||||
|
"default_tnt_side.png",
|
||||||
|
"default_tnt_side.png",
|
||||||
|
"default_tnt_side.png",
|
||||||
|
"mcl_minecarts_minecart.png",
|
||||||
|
}})
|
||||||
|
else
|
||||||
|
self.object:set_properties({textures =
|
||||||
|
{
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_tnt_blink.png",
|
||||||
|
"mcl_minecarts_minecart.png",
|
||||||
|
}})
|
||||||
|
end
|
||||||
|
self._blinktimer = tnt.BLINKTIMER
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if self._punched then
|
if self._punched then
|
||||||
vel = vector.add(vel, self._velocity)
|
vel = vector.add(vel, self._velocity)
|
||||||
self.object:set_velocity(vel)
|
self.object:set_velocity(vel)
|
||||||
|
@ -224,6 +310,10 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
||||||
minetest.swap_node(rou_old, newnode)
|
minetest.swap_node(rou_old, newnode)
|
||||||
mesecon.receptor_off(rou_old)
|
mesecon.receptor_off(rou_old)
|
||||||
end
|
end
|
||||||
|
-- Activate minecart if on activator rail
|
||||||
|
if node_old.name == "mcl_minecarts:activator_rail_on" and self.on_activate_by_rail then
|
||||||
|
self:on_activate_by_rail()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local ctrl, player = nil, nil
|
local ctrl, player = nil, nil
|
||||||
|
@ -483,7 +573,7 @@ Register a minecart
|
||||||
* creative: If false, don't show in Creative Inventory
|
* creative: If false, don't show in Creative Inventory
|
||||||
]]
|
]]
|
||||||
local function register_minecart(itemstring, entity_id, description, longdesc, usagehelp, mesh, textures, icon, drop, on_rightclick, on_activate_by_rail, creative)
|
local function register_minecart(itemstring, entity_id, description, longdesc, usagehelp, mesh, textures, icon, drop, on_rightclick, on_activate_by_rail, creative)
|
||||||
register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
register_entity(entity_id, mesh, textures, drop, on_rightclick, on_activate_by_rail)
|
||||||
register_craftitem(itemstring, entity_id, description, longdesc, usagehelp, icon, creative)
|
register_craftitem(itemstring, entity_id, description, longdesc, usagehelp, icon, creative)
|
||||||
if minetest.get_modpath("doc_identifier") ~= nil then
|
if minetest.get_modpath("doc_identifier") ~= nil then
|
||||||
doc.sub.identifier.register_object(entity_id, "craftitems", itemstring)
|
doc.sub.identifier.register_object(entity_id, "craftitems", itemstring)
|
||||||
|
@ -651,8 +741,25 @@ register_minecart(
|
||||||
},
|
},
|
||||||
"mcl_minecarts_minecart_tnt.png",
|
"mcl_minecarts_minecart_tnt.png",
|
||||||
{"mcl_minecarts:minecart", "mcl_tnt:tnt"},
|
{"mcl_minecarts:minecart", "mcl_tnt:tnt"},
|
||||||
nil, nil, false
|
-- Ingite
|
||||||
)
|
function(self, clicker)
|
||||||
|
if not clicker or not clicker:is_player() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if self._boomtimer then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local held = clicker:get_wielded_item()
|
||||||
|
if held:get_name() == "mcl_fire:flint_and_steel" then
|
||||||
|
if not minetest.settings:get_bool("creative_mode") then
|
||||||
|
held:add_wear(65535/65) -- 65 uses
|
||||||
|
local index = clicker:get_wielded_index()
|
||||||
|
local inv = clicker:get_inventory()
|
||||||
|
inv:set_stack("main", index, held)
|
||||||
|
end
|
||||||
|
activate_tnt_minecart(self)
|
||||||
|
end
|
||||||
|
end, activate_tnt_minecart, false)
|
||||||
|
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
|
|
|
@ -129,6 +129,7 @@ register_rail("mcl_minecarts:activator_rail",
|
||||||
offstate = "mcl_minecarts:activator_rail",
|
offstate = "mcl_minecarts:activator_rail",
|
||||||
onstate = "mcl_minecarts:activator_rail_on",
|
onstate = "mcl_minecarts:activator_rail_on",
|
||||||
rules = rail_rules_long,
|
rules = rail_rules_long,
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -149,6 +150,20 @@ register_rail("mcl_minecarts:activator_rail_on",
|
||||||
onstate = "mcl_minecarts:activator_rail_on",
|
onstate = "mcl_minecarts:activator_rail_on",
|
||||||
rules = rail_rules_long,
|
rules = rail_rules_long,
|
||||||
},
|
},
|
||||||
|
effector = {
|
||||||
|
-- Activate minecarts
|
||||||
|
action_on = function(pos, node)
|
||||||
|
local pos2 = { x = pos.x, y =pos.y + 1, z = pos.z }
|
||||||
|
local objs = minetest.get_objects_inside_radius(pos2, 1)
|
||||||
|
for _, o in pairs(objs) do
|
||||||
|
local l = o:get_luaentity()
|
||||||
|
if l and string.sub(l.name, 1, 14) == "mcl_minecarts:" and l.on_activate_by_rail then
|
||||||
|
l:on_activate_by_rail()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
drop = "mcl_minecarts:activator_rail",
|
drop = "mcl_minecarts:activator_rail",
|
||||||
},
|
},
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 249 B After Width: | Height: | Size: 257 B |
|
@ -48,6 +48,23 @@ tnt.ignite = function(pos)
|
||||||
core.check_for_falling(pos)
|
core.check_for_falling(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Add smoke particle of entity at pos.
|
||||||
|
-- Intended to be called every step
|
||||||
|
tnt.smoke_step = function(pos)
|
||||||
|
minetest.add_particle({
|
||||||
|
pos = {x=pos.x,y=pos.y+0.5,z=pos.z},
|
||||||
|
velocity = vector.new(math.random() * 0.2 - 0.1, 1.0 + math.random(), math.random() * 0.2 - 0.1),
|
||||||
|
acceleration = vector.new(0, -0.1, 0),
|
||||||
|
expirationtime = 0.15 + math.random() * 0.25,
|
||||||
|
size = 1.0 + math.random(),
|
||||||
|
collisiondetection = false,
|
||||||
|
texture = "tnt_smoke.png"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
tnt.BOOMTIMER = 4
|
||||||
|
tnt.BLINKTIMER = 0.25
|
||||||
|
|
||||||
local TNT_RANGE = 3
|
local TNT_RANGE = 3
|
||||||
|
|
||||||
local sounds
|
local sounds
|
||||||
|
@ -162,19 +179,11 @@ end
|
||||||
|
|
||||||
function TNT:on_step(dtime)
|
function TNT:on_step(dtime)
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
minetest.add_particle({
|
tnt.smoke_step(pos)
|
||||||
pos = {x=pos.x,y=pos.y+0.5,z=pos.z},
|
|
||||||
velocity = vector.new(math.random() * 0.2 - 0.1, 1.0 + math.random(), math.random() * 0.2 - 0.1),
|
|
||||||
acceleration = vector.new(0, -0.1, 0),
|
|
||||||
expirationtime = 0.15 + math.random() * 0.25,
|
|
||||||
size = 1.0 + math.random(),
|
|
||||||
collisiondetection = false,
|
|
||||||
texture = "tnt_smoke.png"
|
|
||||||
})
|
|
||||||
self.timer = self.timer + dtime
|
self.timer = self.timer + dtime
|
||||||
self.blinktimer = self.blinktimer + dtime
|
self.blinktimer = self.blinktimer + dtime
|
||||||
if self.blinktimer > 0.25 then
|
if self.blinktimer > tnt.BLINKTIMER then
|
||||||
self.blinktimer = self.blinktimer - 0.25
|
self.blinktimer = self.blinktimer - tnt.BLINKTIMER
|
||||||
if self.blinkstatus then
|
if self.blinkstatus then
|
||||||
self.object:set_texture_mod("")
|
self.object:set_texture_mod("")
|
||||||
else
|
else
|
||||||
|
@ -182,7 +191,7 @@ function TNT:on_step(dtime)
|
||||||
end
|
end
|
||||||
self.blinkstatus = not self.blinkstatus
|
self.blinkstatus = not self.blinkstatus
|
||||||
end
|
end
|
||||||
if self.timer > 4 then
|
if self.timer > tnt.BOOMTIMER then
|
||||||
tnt.boom(self.object:get_pos())
|
tnt.boom(self.object:get_pos())
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue