v1.0, Hopper added, buffer improved, docu improved, readme reworked

This commit is contained in:
Joachim Stolberg 2020-01-04 15:38:51 +01:00
parent 766bf758d6
commit ca1bde4dbf
18 changed files with 658 additions and 88 deletions

View File

@ -1,7 +1,7 @@
Minecart Minecart
======== ========
**A minecart running through unloaded areas for Minetest v5.0+** **Minecart, the lean railway transportation automation system**
Browse on: ![GitHub](https://github.com/joe7575/minecart) Browse on: ![GitHub](https://github.com/joe7575/minecart)
@ -26,45 +26,71 @@ license).
3. https://github.com/stujones11/railcart/ 3. https://github.com/stujones11/railcart/
Original Features Original Cart Features
----------------- ----------------------
- A fast cart for your railway or roller coaster (up to 7 m/s!) - A fast cart for your railway or roller coaster (up to 7 m/s!)
- Boost and brake rails - Boost and brake rails
- Rail junction switching with the 'right-left' walking keys - Rail junction switching with the 'right-left' walking keys
- Handbrake with the 'back' key - Handbrake with the 'back' key
New Features
------------
- Minecart has its own cart in addition to the standard cart.
- The Minecart can "run" through unloaded areas. This is done by
means of recorded and stored routes. If the area is unloaded
the cart will simply follow the predefined route until an
area is loaded again. In this case the cart will be spawned and
run as usual.
- The Minecart is protected and can't be removed by foreign players.
- The mod adds Protection Landmarks to protect the rails
- To store a route, a player has to place Railway Buffers on both ends,
and use the Minecart to drive the route in both directions.
- The digging of protected Minecarts and rails is only possible as an owner
or with 'minecart' privs.
Use Case Minecart Features
-------- -----------------
The main use of the Minecart is for item transport from mines to warehouses,
ideally by means of an automation mod like Signs Bot. The mod Minecart has its own cart (called Minecart) in addition to the standard cart.
https://github.com/joe7575/signs_bot Minecarts are used for automated item transport on private and public rail networks.
The mod features are:
- configurable timetables and routes for Minecarts
- automated loading/unloading of Minecarts by means of a Minecart Hopper
- rail network protection based on protection blocks called Land Marks
- protection of minecarts and cargo
- Minecarts run through unloaded areas (only the stations/hopper have to be loaded)
- Extra Minecard privs for rail workers
- Ingame documentation (German and English), based on the mod "doc"
Technical Background
--------------------
The Minecart can "run" through unloaded areas. This is done by means of recorded
and stored routes. If the area is unloaded the cart will simply follow the
predefined route until an area is loaded again. In this case the cart will be
spawned and run as usual.
Introduction Introduction
------------ ------------
1. Place your rails and build a route with two ends. Junctions are allowed as 1. Place your rails and build a route with two endpoints. Junctions are allowed
long as each route has its own start and end point. as long as each route has its own start and endpoint.
2. Place a Railway Buffer at both ends. 2. Place a Railway Buffer at both endpoints. (buffers are always needed,
3. Protect your rails with the Protection Landmarks (one Landmark at least every 16 blocks) they store the route and timing information)
4. Drive the route in both directions (route recording), starting at the Railway Buffers. 3. Give both Railway Buffers unique station names, like Oxford and Cambridge
5. Now you can drop items into the Minecart and punch the cart to get started. 4. Drive from buffer to buffer in both directions using a Minecart(!) to record the
6. Sneak+click the cart to get the items back routes (use 'right-left' keys to control the Minecart)
7. Dig the empty cart with a second sneak+Click (as usual). 5. Punch the buffers to check the connection data (e.g. "Oxford: connected to Cambridge")
6. Optional: Configure the Minecart stop time in one or both buffers. The Minecart
will then start automatically after the configured time
7. Optional: Protect your rail network with the Protection Landmarks (one Landmark
at least every 16 nodes/meters)
8. Place a Minecart in front of the buffer and check whether it starts after the
configured time
9. Drop items into the Minecart and punch the cart to start it, or "sneak+click" the
Minecart to get the items back
10. Dig the empty cart with a second "sneak+click" (as usual)
Hopper
------
![hopper](https://github.com/joe7575/minecart/blob/master/hopper.png)
The Hopper is used to load/unload Minecarts.
The Hopper can pull and push items into/out off chests and can drop/pick up items
to/from Minecarts. To unload a Minecart place the hopper below the rail.
To load the Minecart, place the hopper right next to the Minecart.
History History
------- -------
@ -76,3 +102,4 @@ History
2019-05-04 v0.05 Route recording protection added 2019-05-04 v0.05 Route recording protection added
2019-05-22 v0.06 Pick up items from a cart improved 2019-05-22 v0.06 Pick up items from a cart improved
2019-06-23 v0.07 'doc' mod support and German translation added 2019-06-23 v0.07 'doc' mod support and German translation added
2020-01-04 v1.00 Hopper added, buffer improved

View File

@ -1,26 +1,53 @@
--[[
Minecart
========
Copyright (C) 2019-2020 Joachim Stolberg
MIT
See license.txt for more information
]]--
-- for lazy programmers
local M = minetest.get_meta
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local S2P = minetest.string_to_pos
local S = minecart.S local S = minecart.S
local CYCLE_TIME = 2
local StopTime = {}
local function formspec(pos)
local name = M(pos):get_string("name")
local time = M(pos):get_int("time")
local s = "size[4,4.2]" ..
"label[0,0;Configuration]" ..
"field[0.5,1.2;3.6,1;name;"..S("Station name")..":;"..name.."]"..
"button_exit[1,3.4;2,1;exit;Save]"
if minecart.hopper_enabled then
return s.."field[0.5,2.5;3.6,1;time;"..S("Stop time/sec")..":;"..time.."]"
end
return s
end
local function remote_station_name(pos)
local route = minecart.get_route(P2S(pos))
if route and route.dest_pos then
local pos2 = S2P(route.dest_pos)
return M(pos2):get_string("name")
end
return "none"
end
local function on_punch(pos, node, puncher) local function on_punch(pos, node, puncher)
local start_key = P2S(pos) local name = M(pos):get_string("name")
local route = minecart.get_route(start_key) M(pos):set_string("infotext", name..": "..S("connected to").." "..remote_station_name(pos))
if next(route.waypoints) then M(pos):set_string("formspec", formspec(pos))
minetest.chat_send_player(puncher:get_player_name(), if minecart.hopper_enabled then
S("[minecart] Route available")) minetest.get_node_timer(pos):start(CYCLE_TIME)
local no_cart = true
for key,item in pairs(minecart.CartsOnRail) do
if item.start_key == start_key or item.start_key == route.dest_pos then
local pos, vel = minecart.calc_pos_and_vel(item)
minetest.chat_send_player(puncher:get_player_name(), S("[minecart] One cart at").." "..
P2S(pos)..", "..S("velocity").." "..vector.length(vel))
no_cart = false
end
end
if no_cart then
minetest.chat_send_player(puncher:get_player_name(), S("[minecart] No cart available"))
end
else
minetest.chat_send_player(puncher:get_player_name(), S("[minecart] No route stored!"))
end end
end end
@ -49,12 +76,49 @@ minetest.register_node("minecart:buffer", {
fixed = {-8/16, -8/16, -8/16, 8/16, 8/16, 8/16}, fixed = {-8/16, -8/16, -8/16, 8/16, 8/16, 8/16},
}, },
after_place_node = function(pos, placer) after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos) M(pos):set_string("owner", placer:get_player_name())
meta:set_string("owner", placer:get_player_name())
minecart.del_route(minetest.pos_to_string(pos)) minecart.del_route(minetest.pos_to_string(pos))
M(pos):set_string("formspec", formspec(pos))
if minecart.hopper_enabled then
minetest.get_node_timer(pos):start(CYCLE_TIME)
end
end,
on_timer = function(pos, elapsed)
local time = M(pos):get_int("time")
if time > 0 then
local hash = minetest.hash_node_position(pos)
local param2 = (minetest.get_node(pos).param2 + 2) % 4
if minecart.check_cart(pos, param2) then
if StopTime[hash] then
if StopTime[hash] < minetest.get_gametime() then
StopTime[hash] = nil
minecart.punch_cart(pos, param2)
minecart.hopper_resync(pos, param2)
end
else
StopTime[hash] = minetest.get_gametime() + time
end
else
StopTime[hash] = nil
end
end
return true
end, end,
after_dig_node = function(pos) after_dig_node = function(pos)
minecart.del_route(minetest.pos_to_string(pos)) minecart.del_route(minetest.pos_to_string(pos))
local hash = minetest.hash_node_position(pos)
StopTime[hash] = nil
end,
on_receive_fields = function(pos, formname, fields, player)
if M(pos):get_string("owner") ~= player:get_player_name() then
return
end
if (fields.key_enter == "true" or fields.exit == "Save") and fields.name ~= "" then
M(pos):set_string("name", fields.name)
M(pos):set_int("time", tonumber(fields.time) or 0)
M(pos):set_string("formspec", formspec(pos))
M(pos):set_string("infotext", fields.name.." "..S("connected to").." "..remote_station_name(pos))
end
end, end,
on_punch = on_punch, on_punch = on_punch,
sunlight_propagates = true, sunlight_propagates = true,

41
doc.lua
View File

@ -1,3 +1,16 @@
--[[
Minecart
========
Copyright (C) 2019-2020 Joachim Stolberg
MIT
See license.txt for more information
]]--
minecart.doc = {} minecart.doc = {}
if not minetest.get_modpath("doc") then if not minetest.get_modpath("doc") then
@ -10,13 +23,16 @@ local summary_doc = table.concat({
S("Summary"), S("Summary"),
"------------", "------------",
"", "",
S("1. Place your rails and build a route with two ends. Junctions are allowed as long as each route has its own start and end point."), S("1. Place your rails and build a route with two endpoints. Junctions are allowed as long as each route has its own start and endpoint."),
S("2. Place a Railway Buffer at both ends."), S("2. Place a Railway Buffer at both endpoints (buffers are always needed, they store the route and timing information)."),
S("3. Protect your rails with the Protection Landmarks (one Landmark at least every 16 blocks)"), S("3. Give both Railway Buffers unique station names, like Oxford and Cambridge."),
S("4. Drive the route in both directions (route recording), starting at the Railway Buffers."), S("4. Drive from buffer to buffer in both directions using a Minecart(!) to record the routes (use 'right-left' keys to control the Minecart)."),
S("5. Now you can drop items into the Minecart and punch the cart to get started."), S("5. Punch the buffers to check the connection data (e.g. 'Oxford: connected to Cambridge')."),
S("6. Sneak+click the cart to get the items back"), S("6. Optional: Configure the Minecart stop time in one or both buffers. The Minecart will then start automatically after the configured time."),
S("7. Dig the empty cart with a second sneak+Click (as usual).") S("7. Optional: Protect your rail network with the Protection Landmarks (one Landmark at least every 16 nodes/meters)."),
S("8. Place a Minecart in front of the buffer and check whether it starts after the configured time."),
S("9. Drop items into the Minecart and punch the cart to start it, or 'sneak+click' the Minecart to get the items back."),
S("10. Dig the empty cart with a second 'sneak+click' (as usual)."),
}, "\n") }, "\n")
local cart_doc = S("Primary used to transport items. You can drop items into the Minecart and punch the cart to get started. Sneak+click the cart to get the items back") local cart_doc = S("Primary used to transport items. You can drop items into the Minecart and punch the cart to get started. Sneak+click the cart to get the items back")
@ -25,6 +41,9 @@ local buffer_doc = S("Used as buffer on both rail ends. Needed to be able to rec
local landmark_doc = S("Protect your rails with the Landmarks (one Landmark at least every 16 blocks near the rail)") local landmark_doc = S("Protect your rails with the Landmarks (one Landmark at least every 16 blocks near the rail)")
local hopper_doc = S("Used to load/unload Minecart. The Hopper can push/pull items to/from chests and drop/pickup items to/from Minecarts. To unload a Minecart place the hopper below the rail. To load the Minecart, place the hopper right next to the Minecart.")
local function formspec(data) local function formspec(data)
if data.image then if data.image then
local image = "image["..(doc.FORMSPEC.ENTRY_WIDTH - 3)..",0;3,2;"..data.image.."]" local image = "image["..(doc.FORMSPEC.ENTRY_WIDTH - 3)..",0;3,2;"..data.image.."]"
@ -43,7 +62,7 @@ end
doc.add_category("minecart", doc.add_category("minecart",
{ {
name = S("Minecart"), name = S("Minecart"),
description = S("A minecart running through unloaded areas, mainly used for item transportation"), description = S("Minecart, the lean railway transportation automation system"),
sorting = "custom", sorting = "custom",
sorting_data = {"summary", "cart"}, sorting_data = {"summary", "cart"},
build_formspec = formspec, build_formspec = formspec,
@ -69,3 +88,9 @@ doc.add_entry("minecart", "landmark", {
data = {text = landmark_doc, item="minecart:landmark"}, data = {text = landmark_doc, item="minecart:landmark"},
}) })
if minecart.hopper_enabled then
doc.add_entry("minecart", "hopper", {
name = S("Minecart Hopper"),
data = {text=hopper_doc, item="minecart:hopper"},
})
end

166
hopper.lua Normal file
View File

@ -0,0 +1,166 @@
--[[
Minecart
========
Copyright (C) 2019-2020 Joachim Stolberg
MIT
See license.txt for more information
]]--
local NUM_ITEMS = 4
-- for lazy programmers
local M = minetest.get_meta
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local S2P = minetest.string_to_pos
local S = minecart.S
local function scan_for_objects(pos, inv)
for _, object in pairs(minetest.get_objects_inside_radius(pos, 1)) do
local lua_entity = object:get_luaentity()
if not object:is_player() and lua_entity and lua_entity.name == "__builtin:item" then
if lua_entity.itemstring ~= "" then
local stack = ItemStack(lua_entity.itemstring)
if inv:room_for_item("main", stack) then
inv:add_item("main", stack)
object:remove()
end
end
end
end
end
local function pull_push_item(pos, param2)
local items = minecart.take_items(pos, param2, NUM_ITEMS)
if items then
local leftover = minecart.put_items(pos, param2, items)
if leftover then
-- place item back
minecart.untake_items(pos, param2, leftover)
return false
end
return true
end
return false
end
local function push_item(pos, inv, param2)
local taken = minecart.inv_take_items(inv, "main", NUM_ITEMS)
if taken then
local leftover = minecart.put_items(pos, param2, taken)
if leftover then
inv:add_item("main", leftover)
end
end
end
local formspec = "size[8,6.5]"..
"list[context;main;2,0;2,2;]"..
"list[current_player;main;0,2.7;8,4;]"..
"listring[context;main]"..
"listring[current_player;main]"
minetest.register_node("minecart:hopper", {
description = S("Minecart Hopper"),
tiles = {
-- up, down, right, left, back, front
"default_cobble.png^minecart_appl_hopper_top.png",
"default_cobble.png^minecart_appl_hopper.png",
"default_cobble.png^minecart_appl_hopper_right.png",
"default_cobble.png^minecart_appl_hopper.png",
"default_cobble.png^minecart_appl_hopper.png",
"default_cobble.png^minecart_appl_hopper.png",
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-8/16, 2/16, -8/16, 8/16, 8/16, -6/16},
{-8/16, 2/16, 6/16, 8/16, 8/16, 8/16},
{-8/16, 2/16, -8/16, -6/16, 8/16, 8/16},
{ 6/16, 2/16, -8/16, 8/16, 8/16, 8/16},
{-6/16, 0/16, -6/16, 6/16, 3/16, 6/16},
{-5/16, -4/16, -5/16, 5/16, 0/16, 5/16},
{ 0/16, -4/16, -3/16, 11/16, 2/16, 3/16},
},
},
selection_box = {
type = "fixed",
fixed = {
{-8/16, 2/16, -8/16, 8/16, 8/16, 8/16},
{-5/16, -4/16, -5/16, 5/16, 0/16, 5/16},
{ 0/16, -4/16, -3/16, 11/16, 2/16, 3/16},
},
},
on_construct = function(pos)
local inv = M(pos):get_inventory()
inv:set_size('main', 4)
end,
after_place_node = function(pos, placer)
local meta = M(pos)
meta:set_string("owner", placer:get_player_name())
meta:set_string("formspec", formspec)
minetest.get_node_timer(pos):start(2)
end,
on_timer = function(pos, elapsed)
local inv = M(pos):get_inventory()
local param2 = minetest.get_node(pos).param2
param2 = (param2 + 1) % 4 -- output is on the right
if not pull_push_item(pos, param2) then
scan_for_objects({x=pos.x, y=pos.y+1, z=pos.z}, inv)
push_item(pos, inv, param2)
end
return true
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
minetest.get_node_timer(pos):start(2)
return stack:get_count()
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
for _,stack in ipairs(oldmetadata.inventory.main) do
minetest.add_item(pos, stack)
end
end,
-- to prevent items from being dropped when the cart is just launched
minecart_resync = function(pos)
minetest.get_node_timer(pos):stop()
minetest.get_node_timer(pos):start(2)
end,
paramtype = "light",
sunlight_propagates = true,
paramtype2 = "facedir",
groups = {choppy=2, cracky=2, crumbly=2},
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})
minetest.register_craft({
output = "minecart:hopper",
recipe = {
{"default:stone", "", "default:stone"},
{"default:stone", "default:gold_ingot", "default:stone"},
{"", "default:stone", ""},
},
})

BIN
hopper.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

View File

@ -1,12 +1,31 @@
--[[
Minecart
========
Copyright (C) 2019-2020 Joachim Stolberg
MIT
See license.txt for more information
]]--
minecart = {} minecart = {}
minecart.hopper_enabled = minetest.settings:get_bool("minecart_hopper_enabled") ~= false
print("minecart_hopper_enabled", dump(minetest.settings:get_bool("minecart_hopper_enabled")))
minecart.S = minetest.get_translator("minecart") minecart.S = minetest.get_translator("minecart")
local MP = minetest.get_modpath("minecart") local MP = minetest.get_modpath("minecart")
dofile(MP.."/storage.lua") dofile(MP.."/storage.lua")
dofile(MP.."/lib.lua")
dofile(MP.."/routes.lua") dofile(MP.."/routes.lua")
dofile(MP.."/cart_entity.lua") dofile(MP.."/cart_entity.lua")
dofile(MP.."/buffer.lua") dofile(MP.."/buffer.lua")
dofile(MP.."/protection.lua") dofile(MP.."/protection.lua")
if minecart.hopper_enabled then
dofile(MP.."/hopper.lua")
end
dofile(MP.."/doc.lua") dofile(MP.."/doc.lua")
minetest.log("info", "[MOD] Minecart loaded") minetest.log("info", "[MOD] Minecart loaded")

194
lib.lua Normal file
View File

@ -0,0 +1,194 @@
--[[
Minecart
========
Copyright (C) 2019-2020 Joachim Stolberg
MIT
See license.txt for more information
]]--
-- for lazy programmers
local M = minetest.get_meta
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local S2P = minetest.string_to_pos
local S = minecart.S
local RegisteredInventories = {}
local param2_to_dir = {[0]=
{x=0, y=0, z=1},
{x=1, y=0, z=0},
{x=0, y=0, z=-1},
{x=-1, y=0, z=0},
{x=0, y=-1, z=0},
{x=0, y=1, z=0}
}
local function is_air_like(name)
local ndef = minetest.registered_nodes[name]
if ndef and ndef.buildable_to then
return true
end
return false
end
function minecart.get_next_node(pos, param2)
local pos2 = vector.add(pos, param2_to_dir[param2])
local node = minetest.get_node(pos2)
return pos2, node
end
function minecart.check_cart(pos, param2)
if param2 then
pos = minecart.get_next_node(pos, param2)
end
for _, object in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do
if object:get_entity_name() == "minecart:cart" then
return true
end
end
return false
end
local get_next_node = minecart.get_next_node
local check_cart = minecart.check_cart
-- Take the given number of items from the inv.
-- Returns nil if ItemList is empty.
function minecart.inv_take_items(inv, listname, num)
if inv:is_empty(listname) then
return nil
end
local size = inv:get_size(listname)
for idx = 1, size do
local items = inv:get_stack(listname, idx)
if items:get_count() > 0 then
local taken = items:take_item(num)
inv:set_stack(listname, idx, items)
return taken
end
end
return nil
end
function minecart.take_items(pos, param2, num)
local npos, node = get_next_node(pos, (param2 + 2) % 4)
local def = RegisteredInventories[node.name]
local owner = M(pos):get_string("owner")
local inv = minetest.get_inventory({type="node", pos=npos})
if def and inv and (not def.allow_take or def.allow_take(npos, nil, owner)) then
return minecart.inv_take_items(inv, def.take_listname, num)
end
end
function minecart.put_items(pos, param2, stack)
local npos, node = get_next_node(pos, param2)
local def = RegisteredInventories[node.name]
local owner = M(pos):get_string("owner")
local inv = minetest.get_inventory({type="node", pos=npos})
if def and inv and (not def.allow_put or def.allow_put(npos, stack, owner)) then
local leftover = inv:add_item(def.put_listname, stack)
if leftover:get_count() > 0 then
return leftover
end
elseif is_air_like(node.name) or check_cart(npos) then
minetest.add_item(npos, stack)
else
return stack
end
end
function minecart.untake_items(pos, param2, stack)
local npos, node = get_next_node(pos, (param2 + 2) % 4)
local def = RegisteredInventories[node.name]
local inv = minetest.get_inventory({type="node", pos=npos})
if def then
return inv and inv:add_item(def.put_listname, stack)
end
end
function minecart.punch_cart(pos, param2)
local pos2 = minecart.get_next_node(pos, param2)
for _, object in pairs(minetest.get_objects_inside_radius(pos2, 0.5)) do
if object:get_entity_name() == "minecart:cart" then
object:punch(object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = 1},
}, minetest.facedir_to_dir(0))
break -- start only one cart
end
end
end
function minecart.hopper_resync(pos, param2)
local pos2 = minecart.get_next_node(pos, param2)
local pos3 = {x = pos2.x-1, y = pos2.y, z = pos2.z-1}
local pos4 = {x = pos2.x+1, y = pos2.y, z = pos2.z-1}
for _, pos5 in ipairs(minetest.find_nodes_in_area(pos3, pos4, {"minecart:hopper"})) do
local node = minetest.get_node(pos5)
local def = minetest.registered_nodes[node.name]
def.minecart_resync(pos5)
end
end
-- Register inventory node for hopper access
-- (for examples, see below)
function minecart.register_inventory(node_names, def)
for _, name in ipairs(node_names) do
RegisteredInventories[name] = {
allow_put = def.put and def.put.allow_inventory_put,
put_listname = def.put and def.put.listname,
allow_take = def.take and def.take.allow_inventory_take,
take_listname = def.take and def.take.listname,
}
end
end
minecart.register_inventory({"default:chest", "default:chest_open"}, {
put = {
listname = "main",
},
take = {
listname = "main",
},
})
minecart.register_inventory({"default:chest_locked", "default:chest_locked_open"}, {
put = {
allow_inventory_put = function(pos, stack, player_name)
local owner = M(pos):get_string("owner")
return owner == player_name
end,
listname = "main",
},
take = {
allow_inventory_take = function(pos, stack, player_name)
local owner = M(pos):get_string("owner")
return owner == player_name
end,
listname = "main",
},
})
minecart.register_inventory({"minecart:hopper"}, {
put = {
allow_inventory_put = function(pos, stack, player_name)
local owner = M(pos):get_string("owner")
return owner == player_name
end,
listname = "main",
},
take = {
allow_inventory_take = function(pos, stack, player_name)
local owner = M(pos):get_string("owner")
return owner == player_name
end,
listname = "main",
},
})

View File

@ -1,29 +1,35 @@
# textdomain: minecart # textdomain: minecart
1. Place your rails and build a route with two ends. Junctions are allowed as long as each route has its own start and end point.=1. Baue eine Schienenstrecke mit 2 Enden. Kreuzungen sind zulässig, solange jede Route ihre eigenen Start- und Endepunkt hat. 1. Place your rails and build a route with two endpoints. Junctions are allowed as long as each route has its own start and endpoint.=1. Baue eine Schienenstrecke mit zwei Enden. Kreuzungen sind zulässig, solange jede Route ihre eigenen Start- und Endpunkte hat.
2. Place a Railway Buffer at both ends.=2. Platziere einen Prellbock an beide Schienenenden. 10. Dig the empty cart with a second 'sneak+click' (as usual).=10. Klicke erneut mit gedrückter Shift-Taste auf den Wagen, um diesen zu entfernen.
3. Protect your rails with the Protection Landmarks (one Landmark at least every 16 blocks)=3. Schütze deine Schienen mit Hilfe der Meilensteine (ein Meilenstein mindestens alle 16 Blöcke). 2. Place a Railway Buffer at both endpoints (buffers are always needed, they store the route and timing information).=2. Platziere einen Prellbock an beide Schienenenden (Prellböcke sind zwingend notwendig, sie speichern die Routen- und Zeit-Informationen).
4. Drive the route in both directions (route recording), starting at the Railway Buffers.=4. Fahre die Route in beide Richtungen (um die Route aufzuzeichnen), starte jeweils an den Prellböcken. 3. Give both Railway Buffers unique station names, like Oxford and Cambridge.=3. Gib beiden Prellböcken eindeutige Stationsnamen wie: Stuttgart und München.
5. Now you can drop items into the Minecart and punch the cart to get started.=5. Nun kannst du Gegenstände in ein Cart legen (Taste Q) und dann den Wagen durch Anklicken starten. 4. Drive from buffer to buffer in both directions using a Minecart(!) to record the routes (use 'right-left' keys to control the Minecart).=4. Um eine Route aufzuzeichnen, fahre die Route in beide Richtungen von Prellbock zu Prellbock mit einem Minecart Wagen(!). Nutze 'links-rechts' Tasten zur Steuerung.
6. Sneak+click the cart to get the items back=6. Klicke mit gedrückter Shift-Taste auf den Wagen, um Gegenstände auszuladen. 5. Punch the buffers to check the connection data (e.g. 'Oxford: connected to Cambridge').=5. Schlage auf die Prellböcke um die Verbindungsdaten zu prüfen (bspw.: 'München: verbunden mit Stuttgart')
7. Dig the empty cart with a second sneak+Click (as usual).=7. Klicke erneut mit gedrückter Shift-Taste auf den Wagen, um diesen zu entfernen. 6. Optional: Configure the Minecart stop time in one or both buffers. The Minecart will then start automatically after the configured time.=6. Optional: Konfiguriere die Wagenwartezeit in einem oder in beiden Prellböcken. Der Wagen startet dann nach dieser Zeit automatisch.
7. Optional: Protect your rail network with the Protection Landmarks (one Landmark at least every 16 nodes/meters).=7. Optional: Schütze deine Schienen mit Hilfe der Meilensteine (ein Meilenstein mindestens alle 16 Blöcke).
8. Place a Minecart in front of the buffer and check whether it starts after the configured time.=8. Platziere einen Wagen direkt vor einem Prellbock und prüfe, ob er nach der konfigurierten Zeit startet.
9. Drop items into the Minecart and punch the cart to start it, or 'sneak+click' the Minecart to get the items back.=9: Lege Gegenstände in ein Wagen (Taste Q) und starte dann den Wagen durch Anklicken. Klicke mit gedrückter Shift-Taste auf den Wagen, um Gegenstände wieder auszuladen.
A minecart running through unloaded areas, mainly used for item transportation=Ein Wagen, welcher auch durch nicht geladene Kartenbereiche fährt, primär für den Transport von Gegenständen genutzt (Lore) A minecart running through unloaded areas, mainly used for item transportation=Ein Wagen, welcher auch durch nicht geladene Kartenbereiche fährt, primär für den Transport von Gegenständen genutzt (Lore)
Allow to dig/place rails in Minecart Landmark areas=Erlaubt dir, Schienen in Meilensteinbereichen zu setzen/zu entfernen Allow to dig/place rails in Minecart Landmark areas=Erlaubt dir, Schienen in Meilensteinbereichen zu setzen/zu entfernen
Minecart=Minecart Minecart=Minecart
Minecart (Sneak+Click to pick up)=Minecart (Shift+Klick zum Entfernen des Carts) Minecart (Sneak+Click to pick up)=Minecart (Shift+Klick zum Entfernen des Carts)
Minecart Cart=Wagen Minecart Cart=Wagen
Minecart Hopper=Minecart Hopper
Minecart Landmark=Minecart Meilenstein Minecart Landmark=Minecart Meilenstein
Minecart Railway Buffer=Minecart Prellbock Minecart Railway Buffer=Minecart Prellbock
Minecart, the lean railway transportation automation system=Minecart, das schlanke Schienentransport Automatisierungssystem
Primary used to transport items. You can drop items into the Minecart and punch the cart to get started. Sneak+click the cart to get the items back=Primär für den Transport von Gegenständen genutzt. Du kannst Gegenstände in ein Cart legen (Taste Q) und dann den Wagen durch Anklicken starten. Klicke mit gedrückter Shift-Taste auf den Wagen, um die Gegenstände wieder auszuladen Primary used to transport items. You can drop items into the Minecart and punch the cart to get started. Sneak+click the cart to get the items back=Primär für den Transport von Gegenständen genutzt. Du kannst Gegenstände in ein Cart legen (Taste Q) und dann den Wagen durch Anklicken starten. Klicke mit gedrückter Shift-Taste auf den Wagen, um die Gegenstände wieder auszuladen
Protect your rails with the Landmarks (one Landmark at least every 16 blocks near the rail)=Schütze deine Schienen mit Hilfe der Meilensteine (ein Meilenstein mindestens alle 16 Blöcke der Strecke entlang) Protect your rails with the Landmarks (one Landmark at least every 16 blocks near the rail)=Schütze deine Schienen mit Hilfe der Meilensteine (ein Meilenstein mindestens alle 16 Blöcke der Strecke entlang)
Station name=Stationsname
Stop time/sec=Haltezeit/s
Summary=Zusammenfassung Summary=Zusammenfassung
Used as buffer on both rail ends. Needed to be able to record the cart routes=Preckblöcke müssen an beiden Schienenenden platziert sein, so dass Aufzeichnungen der Strecke gemacht werden können. Used as buffer on both rail ends. Needed to be able to record the cart routes=Preckblöcke müssen an beiden Schienenenden platziert sein, so dass Aufzeichnungen der Strecke gemacht werden können.
[minecart] No cart available=[minecart] Kein Wagen verfügbar Used to load/unload Minecart. The Hopper can push/pull items to/from chests and drop/pickup items to/from Minecarts. To unload a Minecart place the hopper below the rail. To load the Minecart, place the hopper right next to the Minecart.=Um Wagen zu be- und entladen. Der Hopper kann Gegenstände aus Kisten Holen und legen, sowie diese in Wagen fallen lassen bzw. aus Wagen entnehmen. Um einen Wagen zu entladen, muss der Hopper unter die Schiene platziert werden. Um einen Wagen zu beladen, muss der Hopper direkt neben die Schiene platziert werden.
[minecart] No route stored!=[minecart] Keine Strecke aufgezeichnet! [minecart] Area is protected!=[minecart] Bereich ist geschützt!
[minecart] One cart at=[minecart] Ein Cart bei
[minecart] Please start at a Railway Buffer!=[minecart] Bitte starte beim Prellbock! [minecart] Please start at a Railway Buffer!=[minecart] Bitte starte beim Prellbock!
[minecart] Recording canceled!=[minecart] Aufzeichnung abgebrochen! [minecart] Recording canceled!=[minecart] Aufzeichnung abgebrochen!
[minecart] Route available=[minecart] Strecke verfügbar
[minecart] Route stored!=[minecart] Strecke gespeichert [minecart] Route stored!=[minecart] Strecke gespeichert
[minecart] Start route recording!=[minecart] Starte die Streckenaufzeichnung! [minecart] Start route recording!=[minecart] Starte die Streckenaufzeichnung!
velocity=Geschwindigkeit connected to=verbunden mit

View File

@ -1,27 +1,31 @@
1. Place your rails and build a route with two ends. Junctions are allowed as long as each route has its own start and end point.= 1. Place your rails and build a route with two endpoints. Junctions are allowed as long as each route has its own start and endpoint.=
2. Place a Railway Buffer at both ends.= 10. Dig the empty cart with a second 'sneak+click' (as usual).=
3. Protect your rails with the Protection Landmarks (one Landmark at least every 16 blocks)= 2. Place a Railway Buffer at both endpoints (buffers are always needed, they store the route and timing information).=
4. Drive the route in both directions (route recording), starting at the Railway Buffers.= 3. Give both Railway Buffers unique station names, like Oxford and Cambridge.=
5. Now you can drop items into the Minecart and punch the cart to get started.= 4. Drive from buffer to buffer in both directions using a Minecart(!) to record the routes (use 'right-left' keys to control the Minecart).=
6. Sneak+click the cart to get the items back= 5. Punch the buffers to check the connection data (e.g. 'Oxford: connected to Cambridge').=
7. Dig the empty cart with a second sneak+Click (as usual).= 6. Optional: Configure the Minecart stop time in one or both buffers. The Minecart will then start automatically after the configured time.=
A minecart running through unloaded areas, mainly used for item transportation= 7. Optional: Protect your rail network with the Protection Landmarks (one Landmark at least every 16 nodes/meters).=
8. Place a Minecart in front of the buffer and check whether it starts after the configured time.=
9. Drop items into the Minecart and punch the cart to start it, or 'sneak+click' the Minecart to get the items back.=
Allow to dig/place rails in Minecart Landmark areas= Allow to dig/place rails in Minecart Landmark areas=
Minecart= Minecart=
Minecart (Sneak+Click to pick up)= Minecart (Sneak+Click to pick up)=
Minecart Cart= Minecart Cart=
Minecart Hopper=
Minecart Landmark= Minecart Landmark=
Minecart Railway Buffer= Minecart Railway Buffer=
Minecart, the lean railway transportation automation system=
Primary used to transport items. You can drop items into the Minecart and punch the cart to get started. Sneak+click the cart to get the items back= Primary used to transport items. You can drop items into the Minecart and punch the cart to get started. Sneak+click the cart to get the items back=
Protect your rails with the Landmarks (one Landmark at least every 16 blocks near the rail)= Protect your rails with the Landmarks (one Landmark at least every 16 blocks near the rail)=
Station name=
Stop time/sec=
Summary= Summary=
Used as buffer on both rail ends. Needed to be able to record the cart routes= Used as buffer on both rail ends. Needed to be able to record the cart routes=
[minecart] No cart available= Used to load/unload Minecart. The Hopper can push/pull items to/from chests and drop/pickup items to/from Minecarts. To unload a Minecart place the hopper below the rail. To load the Minecart, place the hopper right next to the Minecart.=
[minecart] No route stored!= [minecart] Area is protected!=
[minecart] One cart at=
[minecart] Please start at a Railway Buffer!= [minecart] Please start at a Railway Buffer!=
[minecart] Recording canceled!= [minecart] Recording canceled!=
[minecart] Route available=
[minecart] Route stored!= [minecart] Route stored!=
[minecart] Start route recording!= [minecart] Start route recording!=
velocity= connected to=

View File

@ -1,3 +1,4 @@
name=minecart name=minecart
depends = default,carts depends = default,carts
description = A minecart running through unloaded areas optional_depends = doc
description = Minecart, the lean railway transportation automation system

View File

@ -1,3 +1,15 @@
--[[
Minecart
========
Copyright (C) 2019-2020 Joachim Stolberg
MIT
See license.txt for more information
]]--
local S = minecart.S local S = minecart.S
local RANGE = 8 local RANGE = 8
@ -73,7 +85,7 @@ minetest.register_node("minecart:landmark", {
return true return true
end end
minetest.chat_send_player(digger:get_player_name(), minetest.chat_send_player(digger:get_player_name(),
S("[minecart] Area is protected! (owner: "..meta:get_string("owner")..")")) S("[minecart] Area is protected!").." (owner: "..meta:get_string("owner")..")")
return false return false
end, end,

View File

@ -1,4 +1,19 @@
--[[
Minecart
========
Copyright (C) 2019-2020 Joachim Stolberg
MIT
See license.txt for more information
]]--
-- for lazy programmers
local M = minetest.get_meta
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local S2P = minetest.string_to_pos
local S = minecart.S local S = minecart.S
local CartsOnRail = minecart.CartsOnRail local CartsOnRail = minecart.CartsOnRail
@ -74,7 +89,9 @@ end
function minecart.set_junction(self, pos, dir, switch_keys) function minecart.set_junction(self, pos, dir, switch_keys)
local junctions = CartsOnRail[self.myID] and CartsOnRail[self.myID].junctions local junctions = CartsOnRail[self.myID] and CartsOnRail[self.myID].junctions
if junctions then if junctions then
self.junctions[minetest.pos_to_string(vector.round(pos))] = {dir, switch_keys} if self.junctions then
self.junctions[minetest.pos_to_string(vector.round(pos))] = {dir, switch_keys}
end
end end
end end

2
settingtypes.txt Normal file
View File

@ -0,0 +1,2 @@
# If enabled, allows the complete automation of Minecarts by means of Hopper and station stop times.
minecart_hopper_enabled (Hopper enabled) bool true

View File

@ -1,4 +1,21 @@
local S = function(pos) if pos then return minetest.pos_to_string(pos) end end --[[
Minecart
========
Copyright (C) 2019-2020 Joachim Stolberg
MIT
See license.txt for more information
]]--
-- for lazy programmers
local M = minetest.get_meta
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local S2P = minetest.string_to_pos
local S = minecart.S
local DAYS_VALID = (30 * 72) -- 30 real days local DAYS_VALID = (30 * 72) -- 30 real days
local storage = minetest.get_mod_storage() local storage = minetest.get_mod_storage()

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

16
textures/shrink.py Normal file
View File

@ -0,0 +1,16 @@
import os, fnmatch
print ">>> Convert"
for filename in os.listdir("./"):
if fnmatch.fnmatch(filename, "*.png"):
print(filename)
os.system("pngquant --skip-if-larger --quality=8-32 --output ./%s.new ./%s" % (filename, filename))
print "\n>>> Copy"
for filename in os.listdir("./"):
if fnmatch.fnmatch(filename, "*.new"):
print(filename)
os.remove("./" + filename[:-4])
os.rename("./" + filename, "./" + filename[:-4])