First commit

master
PilzAdam 2012-08-16 01:52:54 +02:00
commit 9cf78d738f
30 changed files with 1467 additions and 0 deletions

55
README.txt Normal file
View File

@ -0,0 +1,55 @@
===CARTS MOD for MINETEST-C55===
by PilzAdam
Version 30
Introduction:
This mod adds carts to minetest. There were rails for so long in minetest
but no carts so that they were useless. But this mod brings what many
players all over the world wanted for so long (I think so...).
How to install:
Unzip the archive an place it in minetest-base-directory/mods/minetest/
if you have a windows client or a linux run-in-place client. If you have
a linux system-wide instalation place it in ~/.minetest/mods/minetest/.
If you want to install this mod only in one world create the folder
worldmods/ in your worlddirectory.
For further information or help see:
http://wiki.minetest.com/wiki/Installing_Mods
How to use the mod:
Read the first post at http://minetest.net/forum/viewtopic.php?id=2451
Configuration:
(all variables are in init.lua)
line 4: MAX_SPEED => the maximum speed of the cart
line 9: TRANSPORT_PLAYER => transport the player like a normal item
(this is very laggy NOT RECOMMENDED)
line 13: SOUND_FILES => a table with all soundfiles and there length. To
add your own files copy them into carts/sounds (only .ogg files
are supported) and add there name (without ".ogg") and there
lenght (in seconds) to the table.
line 21: SOUND_GAIN => the gain of the sound.
line 27: RAILS => blocks that are treated as rails.
License:
Sourcecode: WTFPL (see below)
Sound: WTFPL (provided from Ragnarok)
Graphics: CC0 (provided from kddekadenz)
See also:
http://minetest.net/
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

16
box.lua Normal file
View File

@ -0,0 +1,16 @@
minetest.register_node("carts:cart_box", {
tiles = {"carts_cart_top.png", "carts_cart_bottom.png", "carts_cart_side.png", "carts_cart_side.png", "carts_cart_side.png", "carts_cart_side.png"},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-0.5, -0.45, -0.5, 0.5, 0.5, -0.5+1/16},
{-0.5, -0.45, -0.5, -0.5+1/16, 0.5, 0.5},
{0.5, -0.5, 0.5, -0.5, 0.5, 0.5-1/16},
{0.5, -0.5, 0.5, 0.5-1/16, 0.5, -0.5},
{-0.5, -0.5, -0.5, 0.5, -0.3, 0.5},
},
},
groups = {oddly_breakable_by_hand=3, not_in_creative_inventory=1},
})

43
chest.lua Normal file
View File

@ -0,0 +1,43 @@
minetest.register_node("carts:chest", {
description = "Railchest",
tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png^default_rail.png", "default_chest_side.png^default_rail.png", "default_chest_side.png^default_rail.png", "default_chest_front.png"},
paramtype2 = "facedir",
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3},
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec",
"invsize[8,8;]"..
"label[0.5.0,0;In:]"..
"list[current_name;in;0.5,0.5;3,3;]"..
"label[4.5.0,0;Out:]"..
"list[current_name;out;4.5,0.5;3,3;]"..
"list[current_player;main;0,4;8,4;]")
meta:set_string("infotext", "Railchest")
local inv = meta:get_inventory()
inv:set_size("in", 3*3)
inv:set_size("out", 3*3)
end,
can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos);
local inv = meta:get_inventory()
return (inv:is_empty("in") and inv:is_empty("out"))
end,
})
minetest.register_abm({
nodenames = {"carts:pickup_plate"},
interval = 0,
chance = 1,
action = function(pos)
minetest.env:remove_node(pos)
end
})
minetest.register_craft({
output = '"carts:chest" 1',
recipe = {
{'default:wood', 'default:wood', 'default:wood'},
{'default:wood', 'default:rail', 'default:wood'},
{'default:wood', 'default:wood', 'default:wood'}
}
})

1
depends.txt Normal file
View File

@ -0,0 +1 @@
default

17
functions.lua Normal file
View File

@ -0,0 +1,17 @@
local APPROXIMATION = 0.8
equals = function(num1, num2)
if math.abs(num1-num2) <= APPROXIMATION then
return true
else
return false
end
end
pos_equals = function(pos1, pos2)
if pos1.x == pos2.x and pos1.y == pos2.y and pos1.z == pos2.z then
return true
else
return false
end
end

852
init.lua Normal file
View File

@ -0,0 +1,852 @@
--=========
-- 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})]]
minetest.debug("[cartsDebug] ===get_staticdata()===")
minetest.debug("[cartsDebug] "..minetest.pos_to_string(self.object:getpos()))
local table = {
fahren = self.fahren,
fallen = self.fallen,
bremsen = self.bremsen,
dir = self.dir,
old_dir = self.old_dir,
items = self.items,
weiche = self.weiche,
sound_handler = self.sound_handler,
}
minetest.debug("[cartsDebug] => "..minetest.serialize(table))
self:sound("stop")
return minetest.serialize(table)
end
-- set gravity
function cart:on_activate(staticdata)
self.object:setacceleration({x = 0, y = -10, z = 0})
self.items = {}
if staticdata ~= nil then
minetest.debug("[cartsDebug] ===on_activate()===")
--[[ 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]]
local table = minetest.deserialize(staticdata)
if table ~= nil then
minetest.debug("[cartsDebug] Fuege tabelle ein")
self.fahren = table.fahren
self.fallen = table.fallen
self.bremsen = table.bremsen
self.dir = table.dir
self.old_dir = table.old_dir
self.items = table.items
self.weiche = table.weiche
self.sound_handler = table.sound_handler
if self.fahren then
self:sound("start")
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")

248
mesecons.lua Normal file
View File

@ -0,0 +1,248 @@
if minetest.get_modpath("mesecons") ~= nil then
minetest.after(0, function()
mesecon:register_on_signal_on(function(pos, node)
for i,rail in ipairs(RAILS) do
if node.name == rail then
local carts = minetest.env:get_objects_inside_radius(pos, 1)
for i,cart in ipairs(carts) do
if not cart:is_player() and cart:get_luaentity().name == "carts:cart" and not cart:get_luaentity().fahren then
local self = cart:get_luaentity()
-- find out the direction
local dir_table
if self.old_dir ~= nil then
dir_table = {self.old_dir, "x+", "x-", "z+", "z-"}
else
dir_table = {"x+", "x-", "z+", "z-"}
end
for i,dir in ipairs(dir_table) do
self.dir = dir
if self:get_new_direction() == self.dir then
break
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
end
end
if node.name == "carts:switch_left" then
node.name = "carts:switch_right"
minetest.env:set_node(pos, node)
local par2 = minetest.env:get_node(pos).param2
if par2 == 0 then
pos.z = pos.z-1
elseif par2 == 1 then
pos.x = pos.x-1
elseif par2 == 2 then
pos.z = pos.z+1
elseif par2 == 3 then
pos.x = pos.x+1
end
for i,rail in ipairs(RAILS) do
if minetest.env:get_node(pos).name == rail then
local meta = minetest.env:get_meta(pos)
meta:set_string("rail_direction", "right")
end
end
elseif node.name == "carts:switch_right" then
node.name = "carts:switch_left"
minetest.env:set_node(pos, node)
local par2 = minetest.env:get_node(pos).param2
if par2 == 0 then
pos.z = pos.z-1
elseif par2 == 1 then
pos.x = pos.x-1
elseif par2 == 2 then
pos.z = pos.z+1
elseif par2 == 3 then
pos.x = pos.x+1
end
for i,rail in ipairs(RAILS) do
if minetest.env:get_node(pos).name == rail then
local meta = minetest.env:get_meta(pos)
meta:set_string("rail_direction", "left")
end
end
end
if node.name == "carts:meseconrail_stop_off" then
node.name = "carts:meseconrail_stop_on"
minetest.env:set_node(pos, node)
end
end)
mesecon:register_on_signal_off(function(pos, node)
if node.name == "carts:meseconrail_stop_on" then
node.name = "carts:meseconrail_stop_off"
minetest.env:set_node(pos, node)
local carts = minetest.env:get_objects_inside_radius(pos, 1)
for i,cart in ipairs(carts) do
if not cart:is_player() and cart:get_luaentity().name == "carts:cart" and not cart:get_luaentity().fahren then
local self = cart:get_luaentity()
-- find out the direction
if self.old_dir ~= nil then
self.dir = self.old_dir
else
for i,dir in ipairs({"x+", "x-", "z+", "z-"}) do
self.dir = dir
if self:get_new_direction() == self.dir then
break
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
end
end)
end)
minetest.register_node("carts:meseconrail_off", {
description = "Meseconrail",
drawtype = "raillike",
tiles = {"carts_meseconrail_off.png", "carts_meseconrail_curved_off.png", "carts_meseconrail_t_junction_off.png", "carts_meseconrail_crossing_off.png",},
inventory_image = "carts_meseconrail_off.png",
wield_image = "carts_meseconrail_off.png",
paramtype = "light",
walkable = false,
selection_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
},
groups = {bendy=2,snappy=1,dig_immediate=2},
})
minetest.register_node("carts:meseconrail_on", {
drawtype = "raillike",
tiles = {"carts_meseconrail_on.png", "carts_meseconrail_curved_on.png", "carts_meseconrail_t_junction_on.png", "carts_meseconrail_crossing_on.png",},
paramtype = "light",
light_source = LIGHT_MAX-11,
drop = "carts:meseconrail_off",
walkable = false,
selection_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
},
groups = {bendy=2, snappy=1, dig_immediate=2, not_in_creative_inventory=1},
after_destruct = function(pos, oldnode)
if mesecon ~= nil then
mesecon:receptor_off(pos)
end
end,
})
minetest.register_alias("carts:meseconrail", "carts:meseconrail_off")
minetest.after(0, function()
mesecon:add_receptor_node("carts:meseconrail_on")
mesecon:add_receptor_node_off("carts:meseconrail_off")
end)
minetest.register_abm({
nodenames = {"carts:meseconrail_on"},
interval = 1.0,
chance = 1,
action = function(pos, node)
local tmp = minetest.env:get_objects_inside_radius(pos, 1)
local cart_is_there = false
for i,cart in ipairs(tmp) do
if not cart:is_player() and cart:get_luaentity().name == "carts:cart" then
cart_is_there = true
end
end
if not cart_is_there then
minetest.env:set_node(pos, {name="carts:meseconrail_off"})
if mesecon ~= nil then
mesecon:receptor_off(pos)
end
end
end
})
minetest.register_craft({
output = '"carts:meseconrail_off" 1',
recipe = {
{'default:rail', 'mesecons:mesecon_off', 'default:rail'},
{'default:rail', 'mesecons:mesecon_off', 'default:rail'},
{'default:rail', 'mesecons:mesecon_off', 'default:rail'},
}
})
minetest.register_node("carts:meseconrail_stop_off", {
description = "Meseconrail stop",
drawtype = "raillike",
tiles = {"carts_meseconrail_stop_off.png", "carts_meseconrail_stop_curved_off.png", "carts_meseconrail_stop_t_junction_off.png", "carts_meseconrail_stop_crossing_off.png",},
inventory_image = "carts_meseconrail_stop_off.png",
wield_image = "carts_meseconrail_stop_off.png",
paramtype = "light",
walkable = false,
selection_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
},
groups = {bendy=2,snappy=1,dig_immediate=2},
after_destruct = function(pos, oldnode)
if mesecon ~= nil then
mesecon:receptor_off(pos)
end
end,
})
minetest.register_node("carts:meseconrail_stop_on", {
drawtype = "raillike",
tiles = {"carts_meseconrail_stop_on.png", "carts_meseconrail_stop_curved_on.png", "carts_meseconrail_stop_t_junction_on.png", "carts_meseconrail_stop_crossing_on.png",},
paramtype = "light",
light_source = LIGHT_MAX-11,
drop = "carts:meseconrail_stop_off",
walkable = false,
selection_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
},
groups = {bendy=2, snappy=1, dig_immediate=2, not_in_creative_inventory=1},
after_destruct = function(pos, oldnode)
if mesecon ~= nil then
mesecon:receptor_off(pos)
end
end,
})
minetest.register_alias("carts:meseconrail_stop", "carts:meseconrail_stop_off")
minetest.register_craft({
output = '"carts:meseconrail_stop_off" 1',
recipe = {
{'default:rail', 'mesecons:mesecon_off', 'default:rail'},
{'default:rail', '', 'default:rail'},
{'default:rail', 'mesecons:mesecon_off', 'default:rail'},
}
})
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

235
switches.lua Normal file
View File

@ -0,0 +1,235 @@
minetest.register_node("carts:switch_left", {
paramtype2 = "facedir",
tiles = {"default_wood.png"},
drop = "carts:switch_middle",
groups = {bendy=2, snappy=1, dig_immediate=2, not_in_creative_inventory=1},
on_punch = function(pos, node, puncher)
node.name = "carts:switch_middle"
minetest.env:set_node(pos, node)
local par2 = minetest.env:get_node(pos).param2
if par2 == 0 then
pos.z = pos.z-1
elseif par2 == 1 then
pos.x = pos.x-1
elseif par2 == 2 then
pos.z = pos.z+1
elseif par2 == 3 then
pos.x = pos.x+1
end
for i,rail in ipairs(RAILS) do
if minetest.env:get_node(pos).name == rail then
local meta = minetest.env:get_meta(pos)
meta:set_string("rail_direction", "")
end
end
end,
on_destruct = function(pos)
local par2 = minetest.env:get_node(pos).param2
if par2 == 0 then
pos.z = pos.z-1
elseif par2 == 1 then
pos.x = pos.x-1
elseif par2 == 2 then
pos.z = pos.z+1
elseif par2 == 3 then
pos.x = pos.x+1
end
for i,rail in ipairs(RAILS) do
if minetest.env:get_node(pos).name == rail then
local meta = minetest.env:get_meta(pos)
meta:set_string("rail_direction", "")
end
end
end,
drawtype = "nodebox",
paramtype = "light",
node_box = {
type = "fixed",
fixed = {
-- shaft
{-0.05, -0.5, -0.45, 0.05, -0.4, -0.4},
{-0.1, -0.4, -0.45, 0, -0.3, -0.4},
{-0.15, -0.3, -0.45, -0.05, -0.2, -0.4},
{-0.2, -0.2, -0.45, -0.1, -0.1, -0.4},
{-0.25, -0.1, -0.45, -0.15, 0, -0.4},
{-0.3, 0, -0.45, -0.2, 0.1, -0.4},
-- head
{-0.45, 0.1, -0.5, -0.25, 0.3, -0.35},
},
},
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.35, -0.35},
}
},
walkable = false,
})
minetest.register_node("carts:switch_middle", {
description = "Switch",
paramtype2 = "facedir",
tiles = {"default_wood.png"},
groups = {bendy=2, snappy=1, dig_immediate=2},
on_punch = function(pos, node, puncher)
node.name = "carts:switch_right"
minetest.env:set_node(pos, node)
local par2 = minetest.env:get_node(pos).param2
if par2 == 0 then
pos.z = pos.z-1
elseif par2 == 1 then
pos.x = pos.x-1
elseif par2 == 2 then
pos.z = pos.z+1
elseif par2 == 3 then
pos.x = pos.x+1
end
for i,rail in ipairs(RAILS) do
if minetest.env:get_node(pos).name == rail then
local meta = minetest.env:get_meta(pos)
meta:set_string("rail_direction", "right")
end
end
end,
on_construct = function(pos)
local par2 = minetest.env:get_node(pos).param2
if par2 == 0 then
pos.z = pos.z-1
elseif par2 == 1 then
pos.x = pos.x-1
elseif par2 == 2 then
pos.z = pos.z+1
elseif par2 == 3 then
pos.x = pos.x+1
end
for i,rail in ipairs(RAILS) do
if minetest.env:get_node(pos).name == rail then
local meta = minetest.env:get_meta(pos)
meta:set_string("rail_direction", "")
end
end
end,
on_destruct = function(pos)
local par2 = minetest.env:get_node(pos).param2
if par2 == 0 then
pos.z = pos.z-1
elseif par2 == 1 then
pos.x = pos.x-1
elseif par2 == 2 then
pos.z = pos.z+1
elseif par2 == 3 then
pos.x = pos.x+1
end
for i,rail in ipairs(RAILS) do
if minetest.env:get_node(pos).name == rail then
local meta = minetest.env:get_meta(pos)
meta:set_string("rail_direction", "")
end
end
end,
drawtype = "nodebox",
paramtype = "light",
node_box = {
type = "fixed",
fixed = {
-- shaft
{-0.05, -0.5, -0.45, 0.05, 0.15, -0.4},
-- head
{-0.1, 0.15, -0.5, 0.1, 0.35, -0.35},
},
},
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.35, -0.35},
}
},
walkable = false,
})
minetest.register_node("carts:switch_right", {
paramtype2 = "facedir",
tiles = {"default_wood.png"},
groups = {bendy=2,snappy=1, dig_immediate=2, not_in_creative_inventory=1},
drop = "carts:switch_middle",
on_punch = function(pos, node, puncher)
node.name = "carts:switch_left"
minetest.env:set_node(pos, node)
local par2 = minetest.env:get_node(pos).param2
if par2 == 0 then
pos.z = pos.z-1
elseif par2 == 1 then
pos.x = pos.x-1
elseif par2 == 2 then
pos.z = pos.z+1
elseif par2 == 3 then
pos.x = pos.x+1
end
for i,rail in ipairs(RAILS) do
if minetest.env:get_node(pos).name == rail then
local meta = minetest.env:get_meta(pos)
meta:set_string("rail_direction", "left")
end
end
end,
on_destruct = function(pos)
local par2 = minetest.env:get_node(pos).param2
if par2 == 0 then
pos.z = pos.z-1
elseif par2 == 1 then
pos.x = pos.x-1
elseif par2 == 2 then
pos.z = pos.z+1
elseif par2 == 3 then
pos.x = pos.x+1
end
for i,rail in ipairs(RAILS) do
if minetest.env:get_node(pos).name == rail then
local meta = minetest.env:get_meta(pos)
meta:set_string("rail_direction", "")
end
end
end,
drawtype = "nodebox",
paramtype = "light",
node_box = {
type = "fixed",
fixed = {
-- shaft
{-0.05, -0.5, -0.45, 0.05, -0.4, -0.4},
{0, -0.4, -0.45, 0.1, -0.3, -0.4},
{0.05, -0.3, -0.45, 0.15, -0.2, -0.4},
{0.1, -0.2, -0.45, 0.2, -0.1, -0.4},
{0.15, -0.1, -0.45, 0.25, 0, -0.4},
{0.2, 0, -0.45, 0.3, 0.1, -0.4},
-- head
{0.25, 0.1, -0.5, 0.45, 0.3, -0.35},
},
},
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.35, -0.35},
}
},
walkable = false,
})
minetest.register_alias("carts:switch", "carts:switch_middle")
minetest.register_craft({
output = '"carts:switch_middle" 1',
recipe = {
{'', 'default:rail', ''},
{'default:rail', '', ''},
{'', 'default:rail', ''},
}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

BIN
textures/carts_cart_top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B