Implement TNT minecart
This commit is contained in:
parent
74b79d130b
commit
9dc9c12f29
4 changed files with 150 additions and 19 deletions
|
@ -8,10 +8,29 @@ mcl_minecarts.check_float_time = 15
|
|||
dofile(mcl_minecarts.modpath.."/functions.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
|
||||
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 = {
|
||||
physical = false,
|
||||
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
|
||||
_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
|
||||
_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_pos = nil,
|
||||
_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)
|
||||
-- Initialize
|
||||
local data = minetest.deserialize(staticdata)
|
||||
if type(data) == "table" then
|
||||
self._railtype = data._railtype
|
||||
end
|
||||
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
|
||||
|
||||
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
|
||||
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._old_pos then
|
||||
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
|
||||
end
|
||||
|
||||
cart.on_activate_by_rail = on_activate_by_rail
|
||||
|
||||
function cart:on_step(dtime)
|
||||
local vel = self.object:get_velocity()
|
||||
local update = {}
|
||||
|
@ -152,8 +187,15 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
end
|
||||
end
|
||||
|
||||
-- Explode if already ignited
|
||||
if self._boomtimer then
|
||||
self.object:remove()
|
||||
tnt.boom(pos)
|
||||
return
|
||||
end
|
||||
|
||||
-- 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
|
||||
minetest.add_item(self.object:get_pos(), drop[d])
|
||||
end
|
||||
|
@ -165,7 +207,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
self._last_float_check = 0
|
||||
end
|
||||
|
||||
-- Update furnace texture if out of fuel
|
||||
-- Update furnace stuff
|
||||
if self._fueltime and self._fueltime > 0 then
|
||||
self._fueltime = self._fueltime - dtime
|
||||
if self._fueltime <= 0 then
|
||||
|
@ -184,6 +226,50 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
end
|
||||
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
|
||||
vel = vector.add(vel, self._velocity)
|
||||
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)
|
||||
mesecon.receptor_off(rou_old)
|
||||
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
|
||||
|
||||
local ctrl, player = nil, nil
|
||||
|
@ -483,7 +573,7 @@ Register a minecart
|
|||
* 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)
|
||||
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)
|
||||
if minetest.get_modpath("doc_identifier") ~= nil then
|
||||
doc.sub.identifier.register_object(entity_id, "craftitems", itemstring)
|
||||
|
@ -651,8 +741,25 @@ register_minecart(
|
|||
},
|
||||
"mcl_minecarts_minecart_tnt.png",
|
||||
{"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({
|
||||
|
|
|
@ -129,6 +129,7 @@ register_rail("mcl_minecarts:activator_rail",
|
|||
offstate = "mcl_minecarts:activator_rail",
|
||||
onstate = "mcl_minecarts:activator_rail_on",
|
||||
rules = rail_rules_long,
|
||||
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -149,6 +150,20 @@ register_rail("mcl_minecarts:activator_rail_on",
|
|||
onstate = "mcl_minecarts:activator_rail_on",
|
||||
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",
|
||||
},
|
||||
|
|
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)
|
||||
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 sounds
|
||||
|
@ -162,19 +179,11 @@ end
|
|||
|
||||
function TNT:on_step(dtime)
|
||||
local pos = self.object:get_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"
|
||||
})
|
||||
tnt.smoke_step(pos)
|
||||
self.timer = self.timer + dtime
|
||||
self.blinktimer = self.blinktimer + dtime
|
||||
if self.blinktimer > 0.25 then
|
||||
self.blinktimer = self.blinktimer - 0.25
|
||||
if self.blinktimer > tnt.BLINKTIMER then
|
||||
self.blinktimer = self.blinktimer - tnt.BLINKTIMER
|
||||
if self.blinkstatus then
|
||||
self.object:set_texture_mod("")
|
||||
else
|
||||
|
@ -182,7 +191,7 @@ function TNT:on_step(dtime)
|
|||
end
|
||||
self.blinkstatus = not self.blinkstatus
|
||||
end
|
||||
if self.timer > 4 then
|
||||
if self.timer > tnt.BOOMTIMER then
|
||||
tnt.boom(self.object:get_pos())
|
||||
self.object:remove()
|
||||
end
|
||||
|
|
Reference in a new issue