822 lines
21 KiB
Lua
822 lines
21 KiB
Lua
--=========
|
|
-- Maximum speed of the cart
|
|
--=========
|
|
local MAX_SPEED = 4.5
|
|
--=========
|
|
-- Transport the player like a normal item
|
|
-- Note: This is extremly laggy <- FIXME
|
|
--=========
|
|
TRANSPORT_PLAYER = true
|
|
--=========
|
|
-- The name of the Soundfile
|
|
--=========
|
|
SOUND_FILES = {
|
|
{"carts_curved_rails", 2},
|
|
{"carts_railway_crossover", 2},
|
|
{"carts_straight_rails", 1},
|
|
}
|
|
|
|
--=========
|
|
-- The sound gain
|
|
SOUND_GAIN = 0.8
|
|
--=========
|
|
|
|
--=========
|
|
-- Raillike nodes
|
|
--=========
|
|
RAILS = {"default:rail", "carts:meseconrail_off", "carts:meseconrail_on", "carts:meseconrail_stop_off", "carts:meseconrail_stop_on"}
|
|
|
|
dofile(minetest.get_modpath("carts").."/box.lua")
|
|
|
|
local cart = {
|
|
physical = true,
|
|
collisionbox = {-0.425, -0.425, -0.425, 0.425, 0.425, 0.425},
|
|
visual = "wielditem",
|
|
textures = {"carts:cart_box"},
|
|
visual_size = {x=0.85*2/3, y=0.85*2/3},
|
|
--Variables
|
|
fahren = false, -- true when the cart drives
|
|
fallen = false, -- true when the cart drives downhill
|
|
bremsen = false, -- true when the cart brakes
|
|
dir = nil, -- direction of the cart
|
|
old_dir = nil, -- saves the direction when the cart stops
|
|
items = {}, -- list with transported items
|
|
weiche = {x=nil, y=nil, z=nil}, -- saves the position of the railroad switch (to prevent double direction changes)
|
|
sound_handler = nil, -- soundhandler
|
|
}
|
|
|
|
-- Returns the current speed of the cart
|
|
function cart:get_speed()
|
|
if self.dir == "x+" then
|
|
return self.object:getvelocity().x
|
|
elseif self.dir == "x-" then
|
|
return -1*self.object:getvelocity().x
|
|
elseif self.dir == "z+" then
|
|
return self.object:getvelocity().z
|
|
elseif self.dir == "z-" then
|
|
return -1*self.object:getvelocity().z
|
|
end
|
|
return 0
|
|
end
|
|
|
|
-- Sets the current speed of the cart
|
|
function cart:set_speed(speed)
|
|
local newsp = {x=0, y=0, z=0}
|
|
if self.dir == "x+" then
|
|
newsp.x = speed
|
|
elseif self.dir == "x-" then
|
|
newsp.x = -1*speed
|
|
elseif self.dir == "z+" then
|
|
newsp.z = speed
|
|
elseif self.dir == "z-" then
|
|
newsp.z = -1*speed
|
|
end
|
|
self.object:setvelocity(newsp)
|
|
end
|
|
|
|
-- Sets the acceleration of the cart
|
|
function cart:set_acceleration(staerke)
|
|
if self.dir == "x+" then
|
|
self.object:setacceleration({x=staerke, y=-10, z=0})
|
|
elseif self.dir == "x-" then
|
|
self.object:setacceleration({x=-staerke, y=-10, z=0})
|
|
elseif self.dir == "z+" then
|
|
self.object:setacceleration({x=0, y=-10, z=staerke})
|
|
elseif self.dir == "z-" then
|
|
self.object:setacceleration({x=0, y=-10, z=-staerke})
|
|
end
|
|
end
|
|
|
|
-- Stops the cart
|
|
function cart:stop()
|
|
self.fahren = false
|
|
self.bremsen = false
|
|
self.items = {}
|
|
self.fallen = false
|
|
self.object:setacceleration({x = 0, y = -10, z = 0})
|
|
self:set_speed(0)
|
|
-- stop sound
|
|
self:sound("stop")
|
|
end
|
|
|
|
function cart:sound(arg)
|
|
if arg == "stop" then
|
|
if self.sound_handler ~= nil then
|
|
minetest.sound_stop(self.sound_handler)
|
|
self.sound_handler = nil
|
|
end
|
|
elseif arg == "continue" then
|
|
if self.sound_handler == nil then
|
|
return
|
|
end
|
|
minetest.sound_stop(self.sound_handler)
|
|
local sound = SOUND_FILES[math.random(1, #SOUND_FILES)]
|
|
self.sound_handler = minetest.sound_play(sound[1], {
|
|
object = self.object,
|
|
gain = SOUND_GAIN,
|
|
})
|
|
minetest.after(sound[2], function()
|
|
self:sound("continue")
|
|
end)
|
|
elseif arg == "start" then
|
|
local sound = SOUND_FILES[math.random(1, #SOUND_FILES)]
|
|
self.sound_handler = minetest.sound_play(sound[1], {
|
|
object = self.object,
|
|
gain = SOUND_GAIN,
|
|
})
|
|
minetest.after(sound[2], function()
|
|
self:sound("continue")
|
|
end)
|
|
end
|
|
end
|
|
|
|
-- Returns the direction the cart has to drive
|
|
function cart:get_new_direction(pos)
|
|
if pos == nil then
|
|
pos = self.object:getpos()
|
|
end
|
|
if self.dir == nil then
|
|
return nil
|
|
end
|
|
pos.x = math.floor(0.5+pos.x)
|
|
pos.y = math.floor(0.5+pos.y)
|
|
pos.z = math.floor(0.5+pos.z)
|
|
if self.fallen then
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == rail then
|
|
return "y-"
|
|
end
|
|
end
|
|
end
|
|
if self.dir == "x+" then
|
|
pos.x = pos.x+1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
pos.x = pos.x-1
|
|
local meta = minetest.env:get_meta(pos)
|
|
if meta:get_string("rail_direction") == "right" and not pos_equals(pos, self.weiche) then
|
|
pos.z = pos.z+1
|
|
for i,rail1 in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail1 then
|
|
self.weiche = {x=pos.x, y=pos.y, z=pos.z-1}
|
|
return "z+"
|
|
end
|
|
end
|
|
pos.z = pos.z-1
|
|
elseif meta:get_string("rail_direction") == "left" and not pos_equals(pos, self.weiche) then
|
|
pos.z = pos.z-1
|
|
for i,rail1 in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail1 then
|
|
self.weiche = {x=pos.x, y=pos.y, z=pos.z+1}
|
|
return "z-"
|
|
end
|
|
end
|
|
pos.z = pos.z+1
|
|
end
|
|
|
|
return "x+"
|
|
end
|
|
end
|
|
pos.y = pos.y-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "y-"
|
|
end
|
|
end
|
|
pos.y = pos.y+2
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "y+"
|
|
end
|
|
end
|
|
pos.y = pos.y-1
|
|
pos.x = pos.x-1
|
|
|
|
local tmp = minetest.env:get_meta(pos):get_string("rail_direction")
|
|
if tmp == "left" then
|
|
pos.z = pos.z+1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "z+"
|
|
end
|
|
end
|
|
pos.z = pos.z-1
|
|
elseif tmp == "right" then
|
|
pos.z = pos.z-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "z-"
|
|
end
|
|
end
|
|
pos.z = pos.z+1
|
|
end
|
|
|
|
pos.z = pos.z-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "z-"
|
|
end
|
|
end
|
|
pos.z = pos.z+2
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "z+"
|
|
end
|
|
end
|
|
pos.z = pos.z-1
|
|
elseif self.dir == "x-" then
|
|
pos.x = pos.x-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
pos.x = pos.x+1
|
|
local meta = minetest.env:get_meta(pos)
|
|
if meta:get_string("rail_direction") == "left" and not pos_equals(pos, self.weiche) then
|
|
pos.z = pos.z+1
|
|
for i,rail1 in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail1 then
|
|
self.weiche = {x=pos.x, y=pos.y, z=pos.z-1}
|
|
return "z+"
|
|
end
|
|
end
|
|
pos.z = pos.z-1
|
|
elseif meta:get_string("rail_direction") == "right" and not pos_equals(pos, self.weiche) then
|
|
pos.z = pos.z-1
|
|
for i,rail1 in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail1 then
|
|
self.weiche = {x=pos.x, y=pos.y, z=pos.z+1}
|
|
return "z-"
|
|
end
|
|
end
|
|
pos.z = pos.z+1
|
|
end
|
|
|
|
return "x-"
|
|
end
|
|
end
|
|
pos.y = pos.y-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "y-"
|
|
end
|
|
end
|
|
pos.y = pos.y+2
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "y+"
|
|
end
|
|
end
|
|
pos.y = pos.y-1
|
|
pos.x = pos.x+1
|
|
|
|
local tmp = minetest.env:get_meta(pos):get_string("rail_direction")
|
|
if tmp == "left" then
|
|
pos.z = pos.z-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "z-"
|
|
end
|
|
end
|
|
pos.z = pos.z+1
|
|
elseif tmp == "right" then
|
|
pos.z = pos.z+1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "z+"
|
|
end
|
|
end
|
|
pos.z = pos.z-1
|
|
end
|
|
|
|
pos.z = pos.z+1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "z+"
|
|
end
|
|
end
|
|
pos.z = pos.z-2
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "z-"
|
|
end
|
|
end
|
|
pos.z = pos.z+1
|
|
elseif self.dir == "z+" then
|
|
pos.z = pos.z+1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
pos.z = pos.z-1
|
|
local meta = minetest.env:get_meta(pos)
|
|
if meta:get_string("rail_direction") == "left" and not pos_equals(pos, self.weiche) then
|
|
pos.x = pos.x+1
|
|
for i,rail1 in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail1 then
|
|
self.weiche = {x=pos.x-1, y=pos.y, z=pos.z}
|
|
return "x+"
|
|
end
|
|
end
|
|
pos.x = pos.x-1
|
|
elseif meta:get_string("rail_direction") == "right" and not pos_equals(pos, self.weiche) then
|
|
pos.x = pos.x-1
|
|
for i,rail1 in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail1 then
|
|
self.weiche = {x=pos.x+1, y=pos.y, z=pos.z}
|
|
return "x-"
|
|
end
|
|
end
|
|
pos.x = pos.x+1
|
|
end
|
|
|
|
return "z+"
|
|
end
|
|
end
|
|
pos.y = pos.y-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "y-"
|
|
end
|
|
end
|
|
pos.y = pos.y+2
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "y+"
|
|
end
|
|
end
|
|
pos.y = pos.y-1
|
|
pos.z = pos.z-1
|
|
|
|
local tmp = minetest.env:get_meta(pos):get_string("rail_direction")
|
|
if tmp == "left" then
|
|
pos.x = pos.x-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "x-"
|
|
end
|
|
end
|
|
pos.x = pos.x+1
|
|
elseif tmp == "right" then
|
|
pos.x = pos.x+1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "x+"
|
|
end
|
|
end
|
|
pos.x = pos.x-1
|
|
end
|
|
|
|
pos.x = pos.x+1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "x+"
|
|
end
|
|
end
|
|
pos.x = pos.x-2
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "x-"
|
|
end
|
|
end
|
|
pos.x = pos.x+1
|
|
elseif self.dir == "z-" then
|
|
pos.z = pos.z-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
pos.z = pos.z+1
|
|
local meta = minetest.env:get_meta(pos)
|
|
if meta:get_string("rail_direction") == "right" and not pos_equals(pos, self.weiche) then
|
|
pos.x = pos.x+1
|
|
for i,rail1 in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail1 then
|
|
self.weiche = {x=pos.x-1, y=pos.y, z=pos.z}
|
|
return "x+"
|
|
end
|
|
end
|
|
pos.x = pos.x-1
|
|
elseif meta:get_string("rail_direction") == "left" and not pos_equals(pos, self.weiche) then
|
|
pos.x = pos.x-1
|
|
for i,rail1 in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail1 then
|
|
self.weiche = {x=pos.x+1, y=pos.y, z=pos.z}
|
|
return "x-"
|
|
end
|
|
end
|
|
pos.x = pos.x+1
|
|
end
|
|
|
|
return "z-"
|
|
end
|
|
end
|
|
pos.y = pos.y-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "y-"
|
|
end
|
|
end
|
|
pos.y = pos.y+2
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "y+"
|
|
end
|
|
end
|
|
pos.y = pos.y-1
|
|
pos.z = pos.z+1
|
|
|
|
local tmp = minetest.env:get_meta(pos):get_string("rail_direction")
|
|
if tmp == "left" then
|
|
pos.x = pos.x+1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "x+"
|
|
end
|
|
end
|
|
pos.x = pos.x-1
|
|
elseif tmp == "right" then
|
|
pos.x = pos.x-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "x-"
|
|
end
|
|
end
|
|
pos.x = pos.x+1
|
|
end
|
|
|
|
pos.x = pos.x-1
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "x-"
|
|
end
|
|
end
|
|
pos.x = pos.x+2
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
return "x+"
|
|
end
|
|
end
|
|
pos.x = pos.x-1
|
|
end
|
|
return nil
|
|
end
|
|
|
|
-- This method does several things.
|
|
function cart:on_step(dtime)
|
|
-- if the cart dont drives set gravity and return
|
|
if not self.fahren then
|
|
self.object:setacceleration({x=0, y=-10, z=0})
|
|
return
|
|
end
|
|
|
|
local newdir = self:get_new_direction()
|
|
if newdir == "x+" then
|
|
self.object:setyaw(0)
|
|
elseif newdir == "x-" then
|
|
self.object:setyaw(math.pi)
|
|
elseif newdir == "z+" then
|
|
self.object:setyaw(math.pi/2)
|
|
elseif newdir == "z-" then
|
|
self.object:setyaw(math.pi*3/2)
|
|
end
|
|
if newdir == nil and not self.fallen then
|
|
-- end of rail
|
|
-- chek if the cart derailed
|
|
local pos = self.object:getpos()
|
|
if self.dir == "x+" then
|
|
pos.x = pos.x-1
|
|
elseif self.dir == "x-" then
|
|
pos.x = pos.x+1
|
|
elseif self.dir == "z+" then
|
|
pos.z = pos.z-1
|
|
elseif self.dir == "z-" then
|
|
pos.z = pos.z+1
|
|
end
|
|
local checkdir = self:get_new_direction(pos)
|
|
if checkdir ~= self.dir and checkdir ~= nil then
|
|
self.object:setpos(pos)
|
|
self.dir = checkdir
|
|
self.old_dir = checkdir
|
|
-- change direction
|
|
local speed = self:get_speed()
|
|
self:set_speed(speed)
|
|
else
|
|
-- stop
|
|
self:stop()
|
|
local pos = self.object:getpos()
|
|
pos.x = math.floor(0.5+pos.x)
|
|
pos.z = math.floor(0.5+pos.z)
|
|
self.object:setpos(pos)
|
|
end
|
|
elseif newdir == "y+" then
|
|
-- uphill
|
|
self.fallen = false
|
|
local vel = self.object:getvelocity()
|
|
vel.y = MAX_SPEED
|
|
self.object:setvelocity(vel)
|
|
elseif newdir == "y-" then
|
|
-- downhill
|
|
local vel = self.object:getvelocity()
|
|
vel.y = -2*MAX_SPEED
|
|
self.object:setvelocity(vel)
|
|
self.fallen = true
|
|
elseif newdir ~= self.dir then
|
|
-- curve
|
|
self.fallen = false
|
|
local pos = self.object:getpos()
|
|
-- wait until the cart is nearly on the cornernode
|
|
if equals(pos.x, math.floor(0.5+pos.x)) and equals(pos.y, math.floor(0.5+pos.y)) and equals(pos.z, math.floor(0.5+pos.z)) then
|
|
-- "jump" exacly on the cornernode
|
|
pos.x = math.floor(0.5+pos.x)
|
|
pos.z = math.floor(0.5+pos.z)
|
|
self.object:setpos(pos)
|
|
-- change direction
|
|
local speed = self:get_speed()
|
|
self.dir = newdir
|
|
self.old_dir = newdir
|
|
self:set_speed(speed)
|
|
end
|
|
end
|
|
|
|
-- control speed and acceleration
|
|
if self.bremsen then
|
|
if not equals(self:get_speed(), 0) then
|
|
-- if the cart is still driving -> brake
|
|
self:set_acceleration(-10)
|
|
else
|
|
-- if the cart stand still -> stop
|
|
self:stop()
|
|
end
|
|
else
|
|
if self.fahren and self:get_speed() < MAX_SPEED then
|
|
-- if the cart is too slow -> accelerate
|
|
self:set_acceleration(10)
|
|
else
|
|
self:set_acceleration(0)
|
|
end
|
|
end
|
|
|
|
-- move items
|
|
for i,item in ipairs(self.items) do
|
|
if item:is_player() then
|
|
-- if the item is a player move him 0.5 blocks lowlier
|
|
local pos = self.object:getpos()
|
|
pos.y = pos.y-0.5
|
|
item:setpos(pos)
|
|
else
|
|
item:setpos(self.object:getpos())
|
|
if item:get_luaentity() ~= nil then
|
|
item:setvelocity(self.object:getvelocity())
|
|
end
|
|
end
|
|
end
|
|
|
|
-- if the cart isnt on a railroad switch reset the variable
|
|
local pos_tmp = self.object:getpos()
|
|
pos_tmp.x = math.floor(0.5+pos_tmp.x)
|
|
pos_tmp.y = math.floor(0.5+pos_tmp.y)
|
|
pos_tmp.z = math.floor(0.5+pos_tmp.z)
|
|
if not pos_equals(pos_tmp, self.weiche) then
|
|
self.weiche = {x=nil, y=nil, z=nil}
|
|
end
|
|
|
|
-- search for chests
|
|
for d=-1,1 do
|
|
local pos = {x=self.object:getpos().x+d, y=self.object:getpos().y, z=self.object:getpos().z}
|
|
local name1 = minetest.env:get_node(pos).name
|
|
pos = {x=self.object:getpos().x, y=self.object:getpos().y, z=self.object:getpos().z+d}
|
|
local name2 = minetest.env:get_node(pos).name
|
|
if name1 == "carts:chest" then
|
|
pos = {x=self.object:getpos().x+d, y=self.object:getpos().y, z=self.object:getpos().z}
|
|
elseif name2 == "carts:chest" then
|
|
pos = {x=self.object:getpos().x, y=self.object:getpos().y, z=self.object:getpos().z+d}
|
|
else
|
|
name1 = nil
|
|
end
|
|
if name1 ~= nil then
|
|
pos.x = math.floor(0.5+pos.x)
|
|
pos.y = math.floor(0.5+pos.y)
|
|
pos.z = math.floor(0.5+pos.z)
|
|
local inv = minetest.env:get_meta(pos):get_inventory()
|
|
-- drop items
|
|
local items_tmp = {}
|
|
local inv = minetest.env:get_meta(pos):get_inventory()
|
|
for i,item in ipairs(self.items) do
|
|
if not item:is_player() and item:get_luaentity().itemstring ~= nil and item:get_luaentity().itemstring ~= "" and inv:room_for_item("in", ItemStack(item:get_luaentity().itemstring)) then
|
|
if item:get_luaentity().pickup == nil or not pos_equals(pos, item:get_luaentity().pickup) then
|
|
inv:add_item("in", ItemStack(item:get_luaentity().itemstring))
|
|
item:remove()
|
|
else
|
|
table.insert(items_tmp, item)
|
|
end
|
|
else
|
|
table.insert(items_tmp, item)
|
|
end
|
|
end
|
|
self.items = items_tmp
|
|
|
|
--pick up items
|
|
for i=1,inv:get_size("out") do
|
|
local stack = inv:get_stack("out", i)
|
|
if not stack:is_empty() then
|
|
local item = minetest.env:add_entity(self.object:getpos(), "__builtin:item")
|
|
item:get_luaentity():set_item(stack:get_name().." "..stack:get_count())
|
|
item:get_luaentity().pickup = pos
|
|
table.insert(self.items, item)
|
|
inv:remove_item("out", stack)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- mesecons functions
|
|
if minetest.get_modpath("mesecons") ~= nil then
|
|
local pos = self.object:getpos()
|
|
pos.x = math.floor(0.5+pos.x)
|
|
pos.y = math.floor(0.5+pos.y)
|
|
pos.z = math.floor(0.5+pos.z)
|
|
local name = minetest.env:get_node(pos).name
|
|
if name == "carts:meseconrail_off" then
|
|
minetest.env:set_node(pos, {name="carts:meseconrail_on"})
|
|
if mesecon ~= nil then
|
|
mesecon:receptor_on(pos)
|
|
end
|
|
end
|
|
|
|
if name == "carts:meseconrail_stop_on" then
|
|
self:stop()
|
|
local pos = self.object:getpos()
|
|
pos.x = math.floor(0.5+pos.x)
|
|
pos.z = math.floor(0.5+pos.z)
|
|
self.object:setpos(pos)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- rightclick starts/stops the cart
|
|
function cart:on_rightclick(clicker)
|
|
if self.fahren then
|
|
self.bremsen = true
|
|
else
|
|
-- find out the direction
|
|
local pos_cart = self.object:getpos()
|
|
local pos_player = clicker:getpos()
|
|
local res = {x=pos_cart.x-pos_player.x, z=pos_cart.z-pos_player.z}
|
|
if math.abs(res.x) > math.abs(res.z) then
|
|
if res.x < 0 then
|
|
self.dir = "x-"
|
|
self.old_dir = "x-"
|
|
if self:get_new_direction() ~= "x-" then
|
|
if res.z < 0 then
|
|
self.dir = "z-"
|
|
self.old_dir = "z-"
|
|
else
|
|
self.dir = "z+"
|
|
self.old_dir = "z+"
|
|
end
|
|
if self:get_new_direction() ~= self.dir then
|
|
self.dir = "x-"
|
|
self.old_dir = "x-"
|
|
end
|
|
end
|
|
else
|
|
self.dir = "x+"
|
|
self.old_dir = "x+"
|
|
if self:get_new_direction() ~= "x+" then
|
|
if res.z < 0 then
|
|
self.dir = "z-"
|
|
self.old_dir = "z-"
|
|
else
|
|
self.dir = "z+"
|
|
self.old_dir = "z+"
|
|
end
|
|
if self:get_new_direction() ~= self.dir then
|
|
self.dir = "x+"
|
|
self.old_dir = "x+"
|
|
end
|
|
end
|
|
end
|
|
else
|
|
if res.z < 0 then
|
|
self.dir = "z-"
|
|
self.old_dir = "z-"
|
|
if self:get_new_direction() ~= "z-" then
|
|
if res.x < 0 then
|
|
self.dir = "x-"
|
|
self.old_dir = "x-"
|
|
else
|
|
self.dir = "x+"
|
|
self.old_dir = "x+"
|
|
end
|
|
if self:get_new_direction() ~= self.dir then
|
|
self.dir = "z-"
|
|
self.old_dir = "z-"
|
|
end
|
|
end
|
|
else
|
|
self.dir = "z+"
|
|
self.old_dir = "z+"
|
|
if self:get_new_direction() ~= "z+" then
|
|
if res.x < 0 then
|
|
self.dir = "x-"
|
|
self.old_dir = "x-"
|
|
else
|
|
self.dir = "x+"
|
|
self.old_dir = "x+"
|
|
end
|
|
if self:get_new_direction() ~= self.dir then
|
|
self.dir = "z+"
|
|
self.old_dir = "z+"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- detect items
|
|
local tmp = minetest.env:get_objects_inside_radius(self.object:getpos(), 1)
|
|
for i,item in ipairs(tmp) do
|
|
if not item:is_player() and item:get_luaentity().name ~= "carts:cart" then
|
|
table.insert(self.items, item)
|
|
elseif item:is_player() and TRANSPORT_PLAYER then
|
|
table.insert(self.items, item)
|
|
end
|
|
end
|
|
|
|
-- start sound
|
|
self:sound("start")
|
|
|
|
self.fahren = true
|
|
end
|
|
end
|
|
|
|
-- remove the cart and place it in the inventory
|
|
function cart:on_punch(hitter)
|
|
-- stop sound
|
|
self:sound("stop")
|
|
self.object:remove()
|
|
hitter:get_inventory():add_item("main", "carts:cart")
|
|
end
|
|
|
|
-- save the probprties of the cart if unloaded
|
|
function cart:get_staticdata()
|
|
local str = tostring(self.fahren)
|
|
str = str..","
|
|
if self.fahren then
|
|
str = str..self.dir
|
|
end
|
|
self.object:setvelocity({x=0, y=0, z=0})
|
|
return str
|
|
end
|
|
|
|
-- set gravity
|
|
function cart:on_activate(staticdata)
|
|
self.object:setacceleration({x = 0, y = -10, z = 0})
|
|
self.items = {}
|
|
if staticdata ~= nil then
|
|
-- if the cart was unloaded
|
|
if string.find(staticdata, ",") ~= nil then
|
|
-- restore the probprties
|
|
if string.sub(staticdata, 1, string.find(staticdata, ",")-1)=="true" then
|
|
self.dir = string.sub(staticdata, string.find(staticdata, ",")+1)
|
|
self.old_dir = dir
|
|
self.fahren = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
minetest.register_entity("carts:cart", cart)
|
|
|
|
-- inventoryitem
|
|
minetest.register_craftitem("carts:cart", {
|
|
description = "Cart",
|
|
image = minetest.inventorycube("carts_cart_top.png", "carts_cart_side.png", "carts_cart_side.png"),
|
|
wield_image = "carts_cart_top.png",
|
|
stack_max = 1,
|
|
-- replace it with the object
|
|
on_place = function(itemstack, placer, pointed)
|
|
local pos = pointed.under
|
|
local bool = false
|
|
for i,rail in ipairs(RAILS) do
|
|
if minetest.env:get_node(pos).name == rail then
|
|
bool = true
|
|
end
|
|
end
|
|
if not bool then
|
|
pos = pointed.above
|
|
end
|
|
pos = {x = math.floor(0.5+pos.x), y = math.floor(0.5+pos.y), z = math.floor(0.5+pos.z)}
|
|
minetest.env:add_entity(pos, "carts:cart")
|
|
itemstack:take_item(1)
|
|
return itemstack
|
|
end,
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = '"carts:cart" 1',
|
|
recipe = {
|
|
{'default:steel_ingot', '', 'default:steel_ingot'},
|
|
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}
|
|
}
|
|
})
|
|
|
|
dofile(minetest.get_modpath("carts").."/switches.lua")
|
|
dofile(minetest.get_modpath("carts").."/mesecons.lua")
|
|
dofile(minetest.get_modpath("carts").."/chest.lua")
|
|
dofile(minetest.get_modpath("carts").."/functions.lua")
|