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

master
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
========
**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)
@ -26,45 +26,71 @@ license).
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!)
- Boost and brake rails
- Rail junction switching with the 'right-left' walking keys
- 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
--------
The main use of the Minecart is for item transport from mines to warehouses,
ideally by means of an automation mod like Signs Bot.
https://github.com/joe7575/signs_bot
Minecart Features
-----------------
The mod Minecart has its own cart (called Minecart) in addition to the standard cart.
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
------------
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.
2. Place a Railway Buffer at both ends.
3. Protect your rails with the Protection Landmarks (one Landmark at least every 16 blocks)
4. Drive the route in both directions (route recording), starting at the Railway Buffers.
5. Now you can drop items into the Minecart and punch the cart to get started.
6. Sneak+click the cart to get the items back
7. Dig the empty cart with a second sneak+Click (as usual).
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 endpoints. (buffers are always needed,
they store the route and timing information)
3. Give both Railway Buffers unique station names, like Oxford and Cambridge
4. Drive from buffer to buffer in both directions using a Minecart(!) to record the
routes (use 'right-left' keys to control the Minecart)
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
-------
@ -76,3 +102,4 @@ History
2019-05-04 v0.05 Route recording protection added
2019-05-22 v0.06 Pick up items from a cart improved
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 S2P = minetest.string_to_pos
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 start_key = P2S(pos)
local route = minecart.get_route(start_key)
if next(route.waypoints) then
minetest.chat_send_player(puncher:get_player_name(),
S("[minecart] Route available"))
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!"))
local name = M(pos):get_string("name")
M(pos):set_string("infotext", name..": "..S("connected to").." "..remote_station_name(pos))
M(pos):set_string("formspec", formspec(pos))
if minecart.hopper_enabled then
minetest.get_node_timer(pos):start(CYCLE_TIME)
end
end
@ -49,12 +76,49 @@ minetest.register_node("minecart:buffer", {
fixed = {-8/16, -8/16, -8/16, 8/16, 8/16, 8/16},
},
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name())
M(pos):set_string("owner", placer:get_player_name())
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,
after_dig_node = function(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,
on_punch = on_punch,
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 = {}
if not minetest.get_modpath("doc") then
@ -10,13 +23,16 @@ local summary_doc = table.concat({
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("2. Place a Railway Buffer at both ends."),
S("3. Protect your rails with the Protection Landmarks (one Landmark at least every 16 blocks)"),
S("4. Drive the route in both directions (route recording), starting at the Railway Buffers."),
S("5. Now you can drop items into the Minecart and punch the cart to get started."),
S("6. Sneak+click the cart to get the items back"),
S("7. Dig the empty cart with a second sneak+Click (as usual).")
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 endpoints (buffers are always needed, they store the route and timing information)."),
S("3. Give both Railway Buffers unique station names, like Oxford and Cambridge."),
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. Punch the buffers to check the connection data (e.g. 'Oxford: connected to Cambridge')."),
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. 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")
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 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)
if data.image then
local image = "image["..(doc.FORMSPEC.ENTRY_WIDTH - 3)..",0;3,2;"..data.image.."]"
@ -43,7 +62,7 @@ end
doc.add_category("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_data = {"summary", "cart"},
build_formspec = formspec,
@ -69,3 +88,9 @@ doc.add_entry("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.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")
local MP = minetest.get_modpath("minecart")
dofile(MP.."/storage.lua")
dofile(MP.."/lib.lua")
dofile(MP.."/routes.lua")
dofile(MP.."/cart_entity.lua")
dofile(MP.."/buffer.lua")
dofile(MP.."/protection.lua")
if minecart.hopper_enabled then
dofile(MP.."/hopper.lua")
end
dofile(MP.."/doc.lua")
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
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.
2. Place a Railway Buffer at both ends.=2. Platziere einen Prellbock an beide Schienenenden.
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).
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.
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.
6. Sneak+click the cart to get the items back=6. Klicke mit gedrückter Shift-Taste auf den Wagen, um Gegenstände auszuladen.
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.
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.
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.
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).
3. Give both Railway Buffers unique station names, like Oxford and Cambridge.=3. Gib beiden Prellböcken eindeutige Stationsnamen wie: Stuttgart und München.
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.
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')
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)
Allow to dig/place rails in Minecart Landmark areas=Erlaubt dir, Schienen in Meilensteinbereichen zu setzen/zu entfernen
Minecart=Minecart
Minecart (Sneak+Click to pick up)=Minecart (Shift+Klick zum Entfernen des Carts)
Minecart Cart=Wagen
Minecart Hopper=Minecart Hopper
Minecart Landmark=Minecart Meilenstein
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
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
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
[minecart] No route stored!=[minecart] Keine Strecke aufgezeichnet!
[minecart] One cart at=[minecart] Ein Cart bei
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] Area is protected!=[minecart] Bereich ist geschützt!
[minecart] Please start at a Railway Buffer!=[minecart] Bitte starte beim Prellbock!
[minecart] Recording canceled!=[minecart] Aufzeichnung abgebrochen!
[minecart] Route available=[minecart] Strecke verfügbar
[minecart] Route stored!=[minecart] Strecke gespeichert
[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.=
2. Place a Railway Buffer at both ends.=
3. Protect your rails with the Protection Landmarks (one Landmark at least every 16 blocks)=
4. Drive the route in both directions (route recording), starting at the Railway Buffers.=
5. Now you can drop items into the Minecart and punch the cart to get started.=
6. Sneak+click the cart to get the items back=
7. Dig the empty cart with a second sneak+Click (as usual).=
A minecart running through unloaded areas, mainly used for item transportation=
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.=
10. Dig the empty cart with a second 'sneak+click' (as usual).=
2. Place a Railway Buffer at both endpoints (buffers are always needed, they store the route and timing information).=
3. Give both Railway Buffers unique station names, like Oxford and Cambridge.=
4. Drive from buffer to buffer in both directions using a Minecart(!) to record the routes (use 'right-left' keys to control the Minecart).=
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.=
Allow to dig/place rails in Minecart Landmark areas=
Minecart=
Minecart (Sneak+Click to pick up)=
Minecart Cart=
Minecart Hopper=
Minecart Landmark=
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=
Protect your rails with the Landmarks (one Landmark at least every 16 blocks near the rail)=
Station name=
Stop time/sec=
Summary=
Used as buffer on both rail ends. Needed to be able to record the cart routes=
[minecart] No cart available=
[minecart] No route stored!=
[minecart] One cart at=
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] Area is protected!=
[minecart] Please start at a Railway Buffer!=
[minecart] Recording canceled!=
[minecart] Route available=
[minecart] Route stored!=
[minecart] Start route recording!=
velocity=
connected to=

View File

@ -1,3 +1,4 @@
name=minecart
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 RANGE = 8
@ -73,7 +85,7 @@ minetest.register_node("minecart:landmark", {
return true
end
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
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 S2P = minetest.string_to_pos
local S = minecart.S
local CartsOnRail = minecart.CartsOnRail
@ -74,7 +89,9 @@ end
function minecart.set_junction(self, pos, dir, switch_keys)
local junctions = CartsOnRail[self.myID] and CartsOnRail[self.myID].junctions
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

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 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])