commit 9cf78d738f358ccf62e625d8a714f3728dc9aa1b Author: PilzAdam Date: Thu Aug 16 01:52:54 2012 +0200 First commit diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..dd553f3 --- /dev/null +++ b/README.txt @@ -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 + + 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. diff --git a/box.lua b/box.lua new file mode 100644 index 0000000..0c8eced --- /dev/null +++ b/box.lua @@ -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}, +}) \ No newline at end of file diff --git a/chest.lua b/chest.lua new file mode 100644 index 0000000..b1916be --- /dev/null +++ b/chest.lua @@ -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'} + } +}) diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +default diff --git a/functions.lua b/functions.lua new file mode 100644 index 0000000..99af9b3 --- /dev/null +++ b/functions.lua @@ -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 diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..e70ea5b --- /dev/null +++ b/init.lua @@ -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") diff --git a/mesecons.lua b/mesecons.lua new file mode 100644 index 0000000..b4863f3 --- /dev/null +++ b/mesecons.lua @@ -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 diff --git a/sounds/carts_curved_rails.ogg b/sounds/carts_curved_rails.ogg new file mode 100644 index 0000000..bee25fc Binary files /dev/null and b/sounds/carts_curved_rails.ogg differ diff --git a/sounds/carts_railway_crossover.ogg b/sounds/carts_railway_crossover.ogg new file mode 100644 index 0000000..7eb7019 Binary files /dev/null and b/sounds/carts_railway_crossover.ogg differ diff --git a/sounds/carts_straight_rails.ogg b/sounds/carts_straight_rails.ogg new file mode 100644 index 0000000..8b8d6ab Binary files /dev/null and b/sounds/carts_straight_rails.ogg differ diff --git a/switches.lua b/switches.lua new file mode 100644 index 0000000..f509a0d --- /dev/null +++ b/switches.lua @@ -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', ''}, + } +}) diff --git a/textures/carts_cart_bottom.png b/textures/carts_cart_bottom.png new file mode 100644 index 0000000..f84b1ae Binary files /dev/null and b/textures/carts_cart_bottom.png differ diff --git a/textures/carts_cart_side.png b/textures/carts_cart_side.png new file mode 100644 index 0000000..79f6c32 Binary files /dev/null and b/textures/carts_cart_side.png differ diff --git a/textures/carts_cart_top.png b/textures/carts_cart_top.png new file mode 100644 index 0000000..8140fc7 Binary files /dev/null and b/textures/carts_cart_top.png differ diff --git a/textures/carts_meseconrail_crossing_off.png b/textures/carts_meseconrail_crossing_off.png new file mode 100644 index 0000000..74bb900 Binary files /dev/null and b/textures/carts_meseconrail_crossing_off.png differ diff --git a/textures/carts_meseconrail_crossing_on.png b/textures/carts_meseconrail_crossing_on.png new file mode 100644 index 0000000..ced5344 Binary files /dev/null and b/textures/carts_meseconrail_crossing_on.png differ diff --git a/textures/carts_meseconrail_curved_off.png b/textures/carts_meseconrail_curved_off.png new file mode 100644 index 0000000..e7afbb9 Binary files /dev/null and b/textures/carts_meseconrail_curved_off.png differ diff --git a/textures/carts_meseconrail_curved_on.png b/textures/carts_meseconrail_curved_on.png new file mode 100644 index 0000000..e606b3d Binary files /dev/null and b/textures/carts_meseconrail_curved_on.png differ diff --git a/textures/carts_meseconrail_off.png b/textures/carts_meseconrail_off.png new file mode 100644 index 0000000..543a829 Binary files /dev/null and b/textures/carts_meseconrail_off.png differ diff --git a/textures/carts_meseconrail_on.png b/textures/carts_meseconrail_on.png new file mode 100644 index 0000000..977c76f Binary files /dev/null and b/textures/carts_meseconrail_on.png differ diff --git a/textures/carts_meseconrail_stop_crossing_off.png b/textures/carts_meseconrail_stop_crossing_off.png new file mode 100644 index 0000000..98d4507 Binary files /dev/null and b/textures/carts_meseconrail_stop_crossing_off.png differ diff --git a/textures/carts_meseconrail_stop_crossing_on.png b/textures/carts_meseconrail_stop_crossing_on.png new file mode 100644 index 0000000..af44782 Binary files /dev/null and b/textures/carts_meseconrail_stop_crossing_on.png differ diff --git a/textures/carts_meseconrail_stop_curved_off.png b/textures/carts_meseconrail_stop_curved_off.png new file mode 100644 index 0000000..c09e72a Binary files /dev/null and b/textures/carts_meseconrail_stop_curved_off.png differ diff --git a/textures/carts_meseconrail_stop_curved_on.png b/textures/carts_meseconrail_stop_curved_on.png new file mode 100644 index 0000000..8eadf59 Binary files /dev/null and b/textures/carts_meseconrail_stop_curved_on.png differ diff --git a/textures/carts_meseconrail_stop_off.png b/textures/carts_meseconrail_stop_off.png new file mode 100644 index 0000000..054030e Binary files /dev/null and b/textures/carts_meseconrail_stop_off.png differ diff --git a/textures/carts_meseconrail_stop_on.png b/textures/carts_meseconrail_stop_on.png new file mode 100644 index 0000000..17efb06 Binary files /dev/null and b/textures/carts_meseconrail_stop_on.png differ diff --git a/textures/carts_meseconrail_stop_t_junction_off.png b/textures/carts_meseconrail_stop_t_junction_off.png new file mode 100644 index 0000000..1c85ec2 Binary files /dev/null and b/textures/carts_meseconrail_stop_t_junction_off.png differ diff --git a/textures/carts_meseconrail_stop_t_junction_on.png b/textures/carts_meseconrail_stop_t_junction_on.png new file mode 100644 index 0000000..f75a815 Binary files /dev/null and b/textures/carts_meseconrail_stop_t_junction_on.png differ diff --git a/textures/carts_meseconrail_t_junction_off.png b/textures/carts_meseconrail_t_junction_off.png new file mode 100644 index 0000000..0e1e72c Binary files /dev/null and b/textures/carts_meseconrail_t_junction_off.png differ diff --git a/textures/carts_meseconrail_t_junction_on.png b/textures/carts_meseconrail_t_junction_on.png new file mode 100644 index 0000000..3a8d03f Binary files /dev/null and b/textures/carts_meseconrail_t_junction_on.png differ