rocket/rocket.lua

1227 lines
34 KiB
Lua

--Helper Functions
local function get_sign(i)
if i == 0 then
return 0
else
return i / math.abs(i)
end
end
local function get_velocity(v, yaw, y)
local x = -math.sin(yaw) * v
local z = math.cos(yaw) * v
return {x = x, y = y, z = z}
end
local function get_v(v)
return math.sqrt(v.x ^ 2 + v.z ^ 2)
end
--Entities
--Vertical rocket: lift off, landing
local rocket = {
initial_properties = {
hp_max = 50,
physical = true,
collide_with_objects = false, -- Workaround fix for a MT engine bug
collisionbox = {-0.85, 0.0, -0.85, 0.85, 5.0, 0.85}, --{-0.85, -1.5, -0.85, 0.85, 1.5, 0.85},
visual = "mesh",
mesh = "rocket.obj",
visual_size = {x = 1.0, y = 1.0, z = 1.0},
textures = {"rocket.png"},
},
-- Custom fields
driver = nil,
removed = false,
v = 0,
vy = 0,
rot = 0,
auto = false,
soundThrust = nil,
}
function rocket.on_punch(self, puncher)
if not puncher or not puncher:is_player() or self.removed then
return
end
local name = puncher:get_player_name()
if self.driver and name == self.driver then
-- Detach
self.driver = nil
puncher:set_detach()
puncher:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
default.player_attached[name] = false
minetest.sound_stop(self.soundThrust)
end
if not self.driver then
-- Move to inventory
self.removed = true
local inv = puncher:get_inventory()
if not (creative and creative.is_enabled_for
and creative.is_enabled_for(name))
or not inv:contains_item("main", "rocket:rocket_item") then
local leftover = inv:add_item("main", "rocket:rocket_item")
if not leftover:is_empty() then
minetest.add_item(self.object:getpos(), leftover)
end
end
minetest.after(0.1, function()
self.object:remove()
end)
end
end
function rocket.on_rightclick(self, clicker)
if not clicker or not clicker:is_player() then
return
end
local name = clicker:get_player_name()
if self.driver and name == self.driver then
-- Detach
self.driver = nil
self.auto = false
clicker:set_detach()
clicker:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
default.player_attached[name] = false
default.player_set_animation(clicker, "stand" , 30)
local pos = clicker:getpos()
minetest.after(0.1, function()
clicker:setpos(pos)
end)
minetest.sound_stop(self.soundThrust)
elseif not self.driver then
-- Attach
local attach = clicker:get_attach()
if attach and attach:get_luaentity() then
local luaentity = attach:get_luaentity()
if luaentity.driver then
luaentity.driver = nil
end
clicker:set_detach()
end
self.driver = name
clicker:set_attach(self.object, "",
{x = 0, y = 20, z = 0}, {x = 0, y = 0, z = 0})
clicker:set_eye_offset({x=0,y=20,z=0},{x=0,y=0,z=0})
default.player_attached[name] = true
minetest.after(0.2, function()
-- default.player_set_animation(clicker, "sit" , 30)
default.player_set_animation(clicker, "stand" , 30)
end)
clicker:set_look_horizontal(self.object:getyaw())
self.soundThrust=minetest.sound_play({name="thrust"},{object = self.object, gain = 2.0, max_hear_distance = 4, loop = true,}) --old: max_hear_distance = 32
--minetest.sound_play({name="fire_fire.3.ogg"},{object = self.object, gain = 2.0, max_hear_distance = 32, loop = true,})
--[[
Fuel Display Hud (abandoned)
local fuel_display = clicker:hud_add({ --HUD
hud_elem_type = "text",
position = {x = 0.5, y = 0.5},
offset = {x = 0, y = 0},
text = "Hello world!",
alignment = {x = 0, y = 0},
scale = {x = 100, y = 100},
})
clicker:hud_remove(fuel_display) --HUD
]]
end
end
on_activate = function(self, staticdata, dtime_s)
self.object:set_armor_groups({immortal = 1})
end
function rocket.on_step(self, dtime)
self.v = get_v(self.object:getvelocity()) * get_sign(self.v)
self.vy = self.object:getvelocity().y
-- Controls
if self.driver then
local driver_objref = minetest.get_player_by_name(self.driver)
if driver_objref then
if driver_objref:get_breath() < 11 then
--Oxygen system, for when in space or an unbreathable atmosphere
driver_objref:set_breath(11)
end
local ctrl = driver_objref:get_player_control()
if ctrl.jump and ctrl.sneak then --if ctrl.up and ctrl.down then
if not self.auto then
self.auto = true
minetest.chat_send_player(self.driver,
"[rocket] Cruise on")
end
elseif ctrl.sneak then --ctrl.down then
--self.v = self.v - 0.1
if self.auto then
self.auto = false
minetest.chat_send_player(self.driver,
"[rocket] Cruise off")
end
--[[
elseif ctrl.up or self.auto then
self.v = self.v + 0.1
--self.v = self.v + 10]]
end
if ctrl.up then
self.v = self.v + 0.1
--self.v = self.v + 10
elseif ctrl.down then
self.v = self.v - 0.1
end
if ctrl.left and ctrl.right and self.vy < 10 then --go into sideways rocket
local sideways_rocket = minetest.add_entity(self.object:getpos(), "rocket:sideways_rocket")
sideways_rocket:setyaw(self.object:getyaw())
default.player_set_animation(driver_objref, "sit" , 30)
driver_objref:set_detach()
driver_objref:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
driver_objref:set_attach(sideways_rocket, "", {x = 0, y = 1, z = 0}, {x = 0, y = 0, z = 0})
minetest.sound_stop(self.soundThrust)
self.object:remove()
--right click after pressing A+D to go into the sideways rocket
elseif ctrl.left then
self.rot = self.rot + 0.001
elseif ctrl.right then
self.rot = self.rot - 0.001
end
if ctrl.jump and (not self.auto) then
if self.vy < 50 then
self.vy = self.vy + 0.075
--self.vy = self.vy + 7.5
end
minetest.add_particlespawner({
amount = 3, --1,
time = 0.2, --0.1,
minpos = {x = 0, y = 0, z = 0},
maxpos = {x = 0, y = 0, z = 0},
minvel = {x = -0.2, y = 0, z = -0.2},
maxvel = {x = 0.3, y = 0.3, z = 0.3},
minacc = {x = 0, y = 0.1, z = 0},
maxacc = {x = 0, y = 0.3, z = 0},
minexptime = 1,
maxexptime = 2.5,
minsize = 4, --1,
maxsize = 10, --4,
attached = self.object,
texture = "rocket_smoke.png",
})
minetest.add_particlespawner({
amount = 1, --1,
time = 1.0, --0.1,
minpos = {x = 0, y = 0, z = 0},
maxpos = {x = 0, y = 0, z = 0},
minvel = {x = -0.2, y = 0, z = -0.2},
maxvel = {x = 0.3, y = 0.3, z = 0.3},
minacc = {x = 0, y = 0.1, z = 0},
maxacc = {x = 0, y = 0.3, z = 0},
minexptime = 0.25, --1
maxexptime = 0.75, --2.5,
minsize = 14, --1,
maxsize = 16, --4,
attached = self.object,
texture = "rocket_boom.png",
})
elseif (not (ctrl.jump or self.auto)) and self.vy > -50 then --elseif ctrl.sneak then
self.vy = self.vy - 0.075
--self.vy = self.vy - 7.5
end
if self.auto and self.vy > 0 and (not ctrl.jump) then
minetest.add_particlespawner({
amount = 3, --1,
time = 0.2, --0.1,
minpos = {x = 0, y = 0, z = 0},
maxpos = {x = 0, y = 0, z = 0},
minvel = {x = -0.2, y = 0, z = -0.2},
maxvel = {x = 0.3, y = 0.3, z = 0.3},
minacc = {x = 0, y = 0.1, z = 0},
maxacc = {x = 0, y = 0.3, z = 0},
minexptime = 1,
maxexptime = 2.5,
minsize = 4, --1,
maxsize = 10, --4,
attached = self.object,
texture = "rocket_smoke.png",
})
minetest.add_particlespawner({
amount = 1, --1,
time = 1.0, --0.1,
minpos = {x = 0, y = 0, z = 0},
maxpos = {x = 0, y = 0, z = 0},
minvel = {x = -0.2, y = 0, z = -0.2},
maxvel = {x = 0.3, y = 0.3, z = 0.3},
minacc = {x = 0, y = 0.1, z = 0},
maxacc = {x = 0, y = 0.3, z = 0},
minexptime = 0.25, --1
maxexptime = 0.75, --2.5,
minsize = 14, --1,
maxsize = 16, --4,
attached = self.object,
texture = "rocket_boom.png",
})
end
--Crash landing with a pilot
local p = self.object:getpos()
local vacuum = "air"
if(minetest.get_modpath("vacuum")) ~= nil then
vacuum = "vacuum:vacuum"
end
local atmos = "air"
if(minetest.get_modpath("other_worlds")) ~= nil then
atmos = ":asteriod:atmos"
end
local p1 = self.object:getpos()
p1.y = p1.y - 1
if minetest.get_node(p1).name ~= "air" and minetest.get_node(p1).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.vy < -10 then
tnt.boom(p, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
minetest.sound_stop(self.soundThrust)
self.object:remove()
driver_objref:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
end
local p2 = self.object:getpos()
p2.y = p2.y + 6
local p3 = self.object:getpos()
p3.y = p3.y + 4
if minetest.get_node(p2).name ~= "air" and minetest.get_node(p2).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.vy > 10 then
tnt.boom(p3, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
minetest.sound_stop(self.soundThrust)
self.object:remove()
driver_objref:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
end
else
-- Player left server while driving
-- In MT 5.0.0 use 'rocket:on_detach_child()' to do this
self.driver = nil
self.auto = false
minetest.log("warning", "[rocket] Driver left server while" ..
" driving. This may cause some 'Pushing ObjectRef to" ..
" removed/deactivated object' warnings.")
end
end
if self.vy > 0 and (not self.driver) then
minetest.add_particlespawner({
amount = 3, --1,
time = 0.2, --0.1,
minpos = {x = 0, y = 0, z = 0},
maxpos = {x = 0, y = 0, z = 0},
minvel = {x = -0.2, y = 0, z = -0.2},
maxvel = {x = 0.3, y = 0.3, z = 0.3},
minacc = {x = 0, y = 0.1, z = 0},
maxacc = {x = 0, y = 0.3, z = 0},
minexptime = 1,
maxexptime = 2.5,
minsize = 4, --1,
maxsize = 10, --4,
attached = self.object,
texture = "rocket_smoke.png",
})
minetest.add_particlespawner({
amount = 1, --1,
time = 1.0, --0.1,
minpos = {x = 0, y = 0, z = 0},
maxpos = {x = 0, y = 0, z = 0},
minvel = {x = -0.2, y = 0, z = -0.2},
maxvel = {x = 0.3, y = 0.3, z = 0.3},
minacc = {x = 0, y = 0.1, z = 0},
maxacc = {x = 0, y = 0.3, z = 0},
minexptime = 0.25, --1
maxexptime = 0.75, --2.5,
minsize = 14, --1,
maxsize = 16, --4,
attached = self.object,
texture = "rocket_boom.png",
})
end
-- Early return for stationary vehicle
if self.v == 0 and self.rot == 0 and self.vy == 0 then
self.object:setpos(self.object:getpos())
return
end
-- Reduction and limiting of linear speed
local s = get_sign(self.v)
self.v = self.v - 0.02 * s
if s ~= get_sign(self.v) then
self.v = 0
end
if math.abs(self.v) > 6 then
self.v = 6 * get_sign(self.v)
end
-- Reduction and limiting of rotation
local sr = get_sign(self.rot)
self.rot = self.rot - 0.0003 * sr
if sr ~= get_sign(self.rot) then
self.rot = 0
end
if math.abs(self.rot) > 0.015 then
self.rot = 0.015 * get_sign(self.rot)
end
-- Reduction and limiting of vertical speed
--[[
local sy = get_sign(self.vy)
self.vy = self.vy - 0.03 * sy
if sy ~= get_sign(self.vy) then
self.vy = 0
end
if math.abs(self.vy) > 4 then
self.vy = 4 * get_sign(self.vy)
end
]]
local new_acce = {x = 0, y = 0, z = 0}
-- Bouyancy in liquids
--[[
local p = self.object:getpos()
p.y = p.y - 1.5
local def = minetest.registered_nodes[minetest.get_node(p).name]
if def and (def.liquidtype == "source" or def.liquidtype == "flowing") then
new_acce = {x = 0, y = 10, z = 0}
end
]]
--Crash landing without a pilot
local p = self.object:getpos()
local vacuum = "air"
if(minetest.get_modpath("vacuum")) ~= nil then
vacuum = "vacuum:vacuum"
end
local atmos = "air"
if(minetest.get_modpath("other_worlds")) ~= nil then
atmos = ":asteriod:atmos"
end
local p1 = self.object:getpos()
p1.y = p1.y - 1
if minetest.get_node(p1).name ~= "air" and minetest.get_node(p1).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.vy < -10 then
tnt.boom(p, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
minetest.sound_stop(self.soundThrust)
self.object:remove()
end
local p2 = self.object:getpos()
p2.y = p2.y + 6
local p3 = self.object:getpos()
p3.y = p3.y + 4
if minetest.get_node(p2).name ~= "air" and minetest.get_node(p2).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.vy > 10 then
tnt.boom(p3, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
minetest.sound_stop(self.soundThrust)
self.object:remove()
end
self.object:setpos(self.object:getpos())
self.object:setvelocity(get_velocity(self.v, self.object:getyaw(), self.vy))
self.object:setacceleration(new_acce)
self.object:setyaw(self.object:getyaw() + (1 + dtime) * self.rot)
end
minetest.register_entity("rocket:rocket", rocket)
--Horizontal rocket: moving in space, docking
local sideways_rocket = {
initial_properties = {
hp_max = 50,
physical = true,
collide_with_objects = false, -- Workaround fix for a MT engine bug
collisionbox = {-1, 0, -1, 1, 1.85, 1}, --old collison box (was ok sometimes, but did not turn): {-0.9, 0.0, -2.5, 0.9, 1.85, 2.5},
visual = "mesh",
mesh = "sideways_rocket.obj",
visual_size = {x = 1.0, y = 1.0, z = 1.0},
textures = {"rocket.png"},
},
-- Custom fields
driver = nil,
removed = false,
v = 0,
vy = 0,
rot = 0,
auto = false,
soundThrust = nil,
}
function sideways_rocket.on_punch(self, puncher)
if not puncher or not puncher:is_player() or self.removed then
return
end
local name = puncher:get_player_name()
if self.driver and name == self.driver then
-- Detach
self.driver = nil
puncher:set_detach()
default.player_attached[name] = false
minetest.sound_stop(self.soundThrust)
end
if not self.driver then
-- Move to inventory
self.removed = true
local inv = puncher:get_inventory()
if not (creative and creative.is_enabled_for
and creative.is_enabled_for(name))
or not inv:contains_item("main", "rocket:rocket_item") then
local leftover = inv:add_item("main", "rocket:rocket_item")
if not leftover:is_empty() then
minetest.add_item(self.object:getpos(), leftover)
end
end
minetest.after(0.1, function()
self.object:remove()
end)
end
end
function sideways_rocket.on_rightclick(self, clicker)
if not clicker or not clicker:is_player() then
return
end
local name = clicker:get_player_name()
if self.driver and name == self.driver then
-- Detach
self.driver = nil
self.auto = false
clicker:set_detach()
default.player_attached[name] = false
default.player_set_animation(clicker, "stand" , 30)
local pos = clicker:getpos()
minetest.after(0.1, function()
clicker:setpos(pos)
end)
minetest.sound_stop(self.soundThrust)
elseif not self.driver then
-- Attach
local attach = clicker:get_attach()
if attach and attach:get_luaentity() then
local luaentity = attach:get_luaentity()
if luaentity.driver then
luaentity.driver = nil
end
clicker:set_detach()
end
self.driver = name
clicker:set_attach(self.object, "",
{x = 0, y = 1, z = 0}, {x = 0, y = 0, z = 0})
default.player_attached[name] = true
minetest.after(0.2, function()
default.player_set_animation(clicker, "sit" , 30)
end)
clicker:set_look_horizontal(self.object:getyaw())
self.soundThrust=minetest.sound_play({name="thrust"},{object = self.object, gain = 2.0, max_hear_distance = 4, loop = true,})--old: max_hear_distance = 32
end
end
on_activate = function(self, staticdata, dtime_s)
self.object:set_armor_groups({immortal = 1})
end
function sideways_rocket.on_step(self, dtime)
self.v = get_v(self.object:getvelocity()) * get_sign(self.v)
self.vy = self.object:getvelocity().y
-- Controls
if self.driver then
local driver_objref = minetest.get_player_by_name(self.driver)
if driver_objref then
if driver_objref:get_breath() < 11 then
--Oxygen system, for when in space or an unbreathable atmosphere
driver_objref:set_breath(11)
end
local ctrl = driver_objref:get_player_control()
if ctrl.up and ctrl.down then
if not self.auto then
self.auto = true
minetest.chat_send_player(self.driver,
"[rocket] Cruise on")
end
elseif ctrl.down then --braking
--self.v = self.v - 0.1
if self.v > 0 and self.v < 0.01 then
self.v = 0
elseif self.v > 0 then
self.v = self.v - 0.1
end
if self.auto then
self.auto = false
minetest.chat_send_player(self.driver,
"[rocket] Cruise off")
end
elseif ctrl.up or self.auto then
--self.v = self.v + 0.1
if self.v < 30.0 then
self.v = self.v + 0.1
end
minetest.add_particlespawner({
amount = 1, --1,
time = 1.0, --0.1,
minpos = {x = 0, y = 0.5, z = 0},
maxpos = {x = 0, y = 0.5, z = 0},
minvel = {x = -0.2, y = 0, z = -0.2},
maxvel = {x = 0.3, y = 0.3, z = 0.3},
minacc = {x = 0, y = 0.1, z = 0},
maxacc = {x = 0, y = 0.3, z = 0},
minexptime = 0.25, --1
maxexptime = 1.0, --2.5,
minsize = 14, --1,
maxsize = 16, --4,
attached = self.object,
texture = "rocket_boom.png",
})
end
if ctrl.left and ctrl.right and self.v < 10 then --go into vertical rocket
local rocket = minetest.add_entity(self.object:getpos(), "rocket:rocket")
rocket:setyaw(self.object:getyaw())
default.player_set_animation(driver_objref, "stand" , 30)
driver_objref:set_detach()
driver_objref:set_eye_offset({x=0,y=20,z=0},{x=0,y=0,z=0})
driver_objref:set_attach(rocket, "", {x = 0, y = 20, z = 0}, {x = 0, y = 0, z = 0})
minetest.sound_stop(self.soundThrust)
self.object:remove()
--right click after pressing A+D to go into the rocket
elseif ctrl.left then
self.rot = self.rot + 0.001
elseif ctrl.right then
self.rot = self.rot - 0.001
end
if ctrl.jump then
self.vy = self.vy + 0.075
elseif ctrl.sneak then
self.vy = self.vy - 0.075
end
--Crashing with a pilot
local p = self.object:getpos()
local vacuum = "air"
if(minetest.get_modpath("vacuum")) ~= nil then
vacuum = "vacuum:vacuum"
end
local atmos = "air"
if(minetest.get_modpath("other_worlds")) ~= nil then
atmos = ":asteriod:atmos"
end
local p1 = self.object:getpos()
p1.x = p1.x + 2
local p2 = self.object:getpos()
p2.x = p2.x - 2
local p3 = self.object:getpos()
p3.z = p3.z + 2
local p4 = self.object:getpos()
p4.x = p4.x - 2
if minetest.get_node(p1).name ~= "air" and minetest.get_node(p1).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.v > 10 then
minetest.sound_stop(self.soundThrust)
self.object:remove()
if driver_objref then
default.player_set_animation(driver_objref, "stand" , 30)
driver_objref:set_detach()
end
tnt.boom(p, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
elseif minetest.get_node(p2).name ~= "air" and minetest.get_node(p2).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.v > 10 then
minetest.sound_stop(self.soundThrust)
self.object:remove()
if driver_objref then
default.player_set_animation(driver_objref, "stand" , 30)
driver_objref:set_detach()
end
tnt.boom(p, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
elseif minetest.get_node(p3).name ~= "air" and minetest.get_node(p3).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.v > 10 then
minetest.sound_stop(self.soundThrust)
self.object:remove()
if driver_objref then
default.player_set_animation(driver_objref, "stand" , 30)
driver_objref:set_detach()
end
tnt.boom(p, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
elseif minetest.get_node(p4).name ~= "air" and minetest.get_node(p4).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.v > 10 then
minetest.sound_stop(self.soundThrust)
self.object:remove()
if driver_objref then
default.player_set_animation(driver_objref, "stand" , 30)
driver_objref:set_detach()
end
tnt.boom(p, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
end
else
-- Player left server while driving
-- In MT 5.0.0 use 'sideways_rocket:on_detach_child()' to do this
self.driver = nil
self.auto = false
minetest.log("warning", "[rocket] Driver left server while" ..
" driving. This may cause some 'Pushing ObjectRef to" ..
" removed/deactivated object' warnings.")
end
end
if self.v > 0 and (not self.driver) then
minetest.add_particlespawner({
amount = 1, --1,
time = 1.0, --0.1,
minpos = {x = 0, y = 0.5, z = 0},
maxpos = {x = 0, y = 0.5, z = 0},
minvel = {x = -0.2, y = 0, z = -0.2},
maxvel = {x = 0.3, y = 0.3, z = 0.3},
minacc = {x = 0, y = 0.1, z = 0},
maxacc = {x = 0, y = 0.3, z = 0},
minexptime = 0.25, --1
maxexptime = 1.0, --2.5,
minsize = 14, --1,
maxsize = 16, --4,
attached = self.object,
texture = "rocket_boom.png",
})
end
-- Early return for stationary vehicle
if self.v == 0 and self.rot == 0 and self.vy == 0 then
self.object:setpos(self.object:getpos())
return
end
-- Reduction and limiting of linear speed
--[[
local s = get_sign(self.v)
self.v = self.v - 0.02 * s
if s ~= get_sign(self.v) then
self.v = 0
end
if math.abs(self.v) > 6 then
self.v = 6 * get_sign(self.v)
end
]]
-- Reduction and limiting of rotation
local sr = get_sign(self.rot)
self.rot = self.rot - 0.0003 * sr
if sr ~= get_sign(self.rot) then
self.rot = 0
end
if math.abs(self.rot) > 0.015 then
self.rot = 0.015 * get_sign(self.rot)
end
-- Reduction and limiting of vertical speed
local sy = get_sign(self.vy)
self.vy = self.vy - 0.03 * sy
if sy ~= get_sign(self.vy) then
self.vy = 0
end
if math.abs(self.vy) > 4 then
self.vy = 4 * get_sign(self.vy)
end
local new_acce = {x = 0, y = 0, z = 0}
-- Bouyancy in liquids
--[[
local p = self.object:getpos()
p.y = p.y - 1.5
local def = minetest.registered_nodes[minetest.get_node(p).name]
if def and (def.liquidtype == "source" or def.liquidtype == "flowing") then
new_acce = {x = 0, y = 10, z = 0}
end
]]
--Crashing without a pilot
local p = self.object:getpos()
local vacuum = "air"
if(minetest.get_modpath("vacuum")) ~= nil then
vacuum = "vacuum:vacuum"
end
local atmos = "air"
if(minetest.get_modpath("other_worlds")) ~= nil then
atmos = ":asteriod:atmos"
end
local p1 = self.object:getpos()
p1.x = p1.x + 2
local p2 = self.object:getpos()
p2.x = p2.x - 2
local p3 = self.object:getpos()
p3.z = p3.z + 2
local p4 = self.object:getpos()
p4.x = p4.x - 2
if minetest.get_node(p1).name ~= "air" and minetest.get_node(p1).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.v > 10 then
minetest.sound_stop(self.soundThrust)
self.object:remove()
if driver_objref then
default.player_set_animation(driver_objref, "stand" , 30)
driver_objref:set_detach()
end
tnt.boom(p, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
elseif minetest.get_node(p2).name ~= "air" and minetest.get_node(p2).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.v > 10 then
minetest.sound_stop(self.soundThrust)
self.object:remove()
if driver_objref then
default.player_set_animation(driver_objref, "stand" , 30)
driver_objref:set_detach()
end
tnt.boom(p, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
elseif minetest.get_node(p3).name ~= "air" and minetest.get_node(p3).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.v > 10 then
minetest.sound_stop(self.soundThrust)
self.object:remove()
if driver_objref then
default.player_set_animation(driver_objref, "stand" , 30)
driver_objref:set_detach()
end
tnt.boom(p, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
elseif minetest.get_node(p4).name ~= "air" and minetest.get_node(p4).name ~= vacuum and minetest.get_node(p1).name ~= atmos and self.v > 10 then
minetest.sound_stop(self.soundThrust)
self.object:remove()
if driver_objref then
default.player_set_animation(driver_objref, "stand" , 30)
driver_objref:set_detach()
end
tnt.boom(p, {
radius = 3,
damage_radius = 6,
sound = "tnt_explode",
explode_center = false,
})
end
self.object:setpos(self.object:getpos())
self.object:setvelocity(get_velocity(self.v, self.object:getyaw(), self.vy))
self.object:setacceleration(new_acce)
self.object:setyaw(self.object:getyaw() + (1 + dtime) * self.rot)
end
minetest.register_entity("rocket:sideways_rocket", sideways_rocket)
--Main Craftitem
minetest.register_craftitem("rocket:rocket_item", {
description = "Space Shuttle",
inventory_image = "rocket_rocket_inv.png",
wield_scale = {x = 1, y = 1, z = 1},
liquids_pointable = true,
on_place = function(itemstack, placer, pointed_thing)
local under = pointed_thing.under
local node = minetest.get_node(under)
local udef = minetest.registered_nodes[node.name]
-- Run any on_rightclick function of pointed node instead
if udef and udef.on_rightclick and
not (placer and placer:is_player() and
placer:get_player_control().sneak) then
return udef.on_rightclick(under, node, placer, itemstack,
pointed_thing) or itemstack
end
if pointed_thing.type ~= "node" then
return itemstack
end
pointed_thing.under.y = pointed_thing.under.y + 0.5 -- + 2
local rocket = minetest.add_entity(pointed_thing.under,
"rocket:rocket")
if rocket then
if placer then
rocket:setyaw(placer:get_look_horizontal())
end
local player_name = placer and placer:get_player_name() or ""
if not (creative and creative.is_enabled_for and
creative.is_enabled_for(player_name)) then
itemstack:take_item()
end
end
return itemstack
end,
})
--Other craftitems
minetest.register_craftitem("rocket:rocket_cone", {
description = "Rocket Cone",
inventory_image = "rocket_cone.png"
})
minetest.register_craftitem("rocket:rocket_thruster", {
description = "Rocket Thruster",
inventory_image = "rocket_thruster.png"
})
minetest.register_craftitem("rocket:rocket_hull", {
description = "Rocket Hull",
inventory_image = "rocket_hull.png"
})
minetest.register_craftitem("rocket:rocket_left_fin", {
description = "Rocket Left Fin",
inventory_image = "rocket_left_fin.png"
})
minetest.register_craftitem("rocket:rocket_right_fin", {
description = "Rocket Right Fin",
inventory_image = "rocket_right_fin.png"
})
--Crafting recipes
minetest.register_craft({
type = "shaped",
output = "rocket:rocket_left_fin",
recipe = {
{"", "", "default:steel_ingot"},
{"", "default:steel_ingot", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}
}
})
minetest.register_craft({
type = "shaped",
output = "rocket:rocket_right_fin",
recipe = {
{"default:steel_ingot", "", ""},
{"default:steel_ingot", "default:steel_ingot", ""},
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}
}
})
minetest.register_craft({
type = "shaped",
output = "rocket:rocket_thruster",
recipe = {
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
{"", "default:steelblock", ""},
{"default:steelblock", "fire:flint_and_steel", "default:steelblock"}
}
})
minetest.register_craft({
type = "shaped",
output = "rocket:rocket_hull",
recipe = {
{"default:steelblock", "rocket:bucket_rocket_fuel", "default:steelblock"},
{"default:steelblock", "rocket:bucket_rocket_fuel", "default:steelblock"},
{"default:steelblock", "rocket:bucket_rocket_fuel", "default:steelblock"}
}
})
minetest.register_craft({
type = "shaped",
output = "rocket:rocket_cone",
recipe = {
{"", "default:steel_ingot", ""},
{"", "stairs:slab_steelblock", ""},
{"stairs:slab_steelblock", "default:steelblock", "stairs:slab_steelblock"}
}
})
minetest.register_craft({
type = "shaped",
output = "rocket:rocket_item",
recipe = {
{"", "rocket:rocket_cone", ""},
{"", "rocket:rocket_hull", ""},
{"rocket:rocket_left_fin", "rocket:rocket_thruster", "rocket:rocket_right_fin"}
}
})
--Liquids
--Oil
minetest.register_node("rocket:oil_source", {
description = "Oil Source",
drawtype = "liquid",
tiles = {
{
name = "rocket_oil_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 2.0,
},
},
},
special_tiles = {
-- New-style water source material (mostly unused)
{
name = "rocket_oil_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 2.0,
},
backface_culling = false,
},
},
alpha = 160,
paramtype = "light",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 1,
liquidtype = "source",
liquid_alternative_flowing = "rocket:oil_flowing",
liquid_alternative_source = "rocket:oil_source",
liquid_viscosity = 1,
liquid_renewable = false,
post_effect_color = {a = 103, r = 45, g = 23, b = 7},
groups = {oil = 3, liquid = 1, flammable = 1},
sounds = default.node_sound_water_defaults(),
})
minetest.register_node("rocket:oil_flowing", {
description = "Flowing Oil",
drawtype = "flowingliquid",
tiles = {"rocket_oil_source.png"},
special_tiles = {
{
name = "rocket_oil_flowing_animated.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 0.8,
},
},
{
name = "rocket_oil_flowing_animated.png",
backface_culling = true,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 0.8,
},
},
},
alpha = 160,
paramtype = "light",
paramtype2 = "flowingliquid",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 1,
liquidtype = "flowing",
liquid_alternative_flowing = "rocket:oil_flowing",
liquid_alternative_source = "rocket:oil_source",
liquid_viscosity = 1,
liquid_renewable = false,
post_effect_color = {a = 150, r = 45, g = 23, b = 7},
groups = {oil = 3, liquid = 1, flammable = 1, not_in_creative_inventory = 1},
sounds = default.node_sound_water_defaults(),
})
bucket.register_liquid(
"rocket:oil_source",
"rocket:oil_flowing",
"rocket:bucket_oil",
"rocket_bucket_oil.png",
"Oil Bucket"
)
--Oil ore
minetest.register_ore({
ore_type = "scatter",
ore = "rocket:oil_source",
wherein = "default:stone",
clust_scarcity = 17 * 17 * 17,
clust_num_ores = 4,
clust_size = 3,
y_min = -255,
y_max = -128,
})
minetest.register_ore({
ore_type = "scatter",
ore = "rocket:oil_source",
wherein = "default:stone",
clust_scarcity = 15 * 15 * 15,
clust_num_ores = 4,
clust_size = 3,
y_min = -31000,
y_max = -256,
})
--Rocket fuel
minetest.register_node("rocket:rocket_fuel_source", {
description = "Rocket Fuel Source",
drawtype = "liquid",
tiles = {
{
name = "rocket_rocket_fuel_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 2.0,
},
},
},
special_tiles = {
-- New-style water source material (mostly unused)
{
name = "rocket_rocket_fuel_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 2.0,
},
backface_culling = false,
},
},
alpha = 160,
paramtype = "light",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 1,
liquidtype = "source",
liquid_alternative_flowing = "rocket:rocket_fuel_flowing",
liquid_alternative_source = "rocket:rocket_fuel_source",
liquid_viscosity = 1,
liquid_renewable = false,
post_effect_color = {a = 103, r = 254, g = 0, b = 30},
groups = {oil = 3, liquid = 1, flammable = 1},
sounds = default.node_sound_water_defaults(),
})
minetest.register_node("rocket:rocket_fuel_flowing", {
description = "Flowing Rocket Fuel",
drawtype = "flowingliquid",
tiles = {"rocket_rocket_fuel_source.png"},
special_tiles = {
{
name = "rocket_rocket_fuel_flowing_animated.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 0.8,
},
},
{
name = "rocket_rocket_fuel_flowing_animated.png",
backface_culling = true,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 0.8,
},
},
},
alpha = 160,
paramtype = "light",
paramtype2 = "flowingliquid",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 1,
liquidtype = "flowing",
liquid_alternative_flowing = "rocket:rocket_fuel_flowing",
liquid_alternative_source = "rocket:rocket_fuel_source",
liquid_viscosity = 1,
liquid_renewable = false,
post_effect_color = {a = 103, r = 254, g = 0, b = 30},
groups = {oil = 3, liquid = 1, flammable = 1, not_in_creative_inventory = 1},
sounds = default.node_sound_water_defaults(),
})
bucket.register_liquid(
"rocket:rocket_fuel_source",
"rocket:rocket_fuel_flowing",
"rocket:bucket_rocket_fuel",
"rocket_bucket_rocket_fuel.png",
"Rocket Fuel Bucket"
)
--Oil refinement recipe
minetest.register_craft({
type = "cooking",
output = "rocket:bucket_rocket_fuel",
recipe = "rocket:bucket_oil",
--cooktime = 5,
})
--Rocket fuel as a fuel
minetest.register_craft({
type = "fuel",
recipe = "rocket:bucket_rocket_fuel",
burntime = 80,
replacements = {{"rocket:bucket_rocket_fuel", "bucket:bucket_empty"}},
})