From f3478e326964b838b9393e37be99cb70084a7907 Mon Sep 17 00:00:00 2001 From: Joachim Stolberg Date: Sun, 5 Mar 2023 11:54:37 +0100 Subject: [PATCH] built on 05/03/2023 11:54:37 --- autobahn/init.lua | 4 +- minecart/README.md | 51 +--- minecart/api.lua | 47 +++- minecart/baselib.lua | 45 ++-- minecart/beduino.lua | 4 +- minecart/doc.lua | 2 +- minecart/entitylib.lua | 66 ++--- minecart/hopper.lua | 10 +- minecart/hopperlib.lua | 12 +- minecart/init.lua | 2 +- minecart/locale/minecart.de.tr | 17 +- minecart/locale/template.txt | 11 +- minecart/minecart.lua | 18 +- minecart/mods_support.lua | 31 ++- minecart/monitoring.lua | 46 ++-- minecart/nodelib.lua | 23 +- minecart/protection.lua | 22 +- minecart/pusher.lua | 2 +- minecart/rails.lua | 102 ++++---- minecart/recording.lua | 28 +-- minecart/signs.lua | 4 +- minecart/storage.lua | 2 +- minecart/terminal.lua | 12 +- minecart/tool.lua | 10 +- networks/README.md | 5 +- networks/init.lua | 4 +- networks/liquid.lua | 5 +- networks/power.lua | 12 +- signs_bot/README.md | 1 + signs_bot/cmd_place.lua | 36 +++ techage/README.md | 20 +- techage/basic_machines/autocrafter.lua | 9 + techage/basic_machines/electronic_fab.lua | 8 +- techage/basic_machines/ta4_chest.lua | 5 +- techage/basic_machines/ta5_chest.lua | 72 ++++-- techage/basis/fly_lib.lua | 110 +++++--- techage/basis/hyperloop.lua | 2 +- techage/basis/liquid_lib.lua | 18 ++ techage/basis/recipe_lib.lua | 2 + techage/basis/shared_inv.lua | 24 +- techage/carts/tank_cart.lua | 2 +- techage/chemistry/ta4_doser.lua | 6 +- techage/coal_power_station/turbine.lua | 4 +- techage/collider/detector.lua | 80 ++++-- techage/collider/inlets.lua | 11 +- techage/collider/magnet.lua | 12 +- techage/doc/manual_DE.lua | 23 +- techage/doc/manual_EN.lua | 19 +- techage/energy_storage/heatexchanger2.lua | 11 +- techage/hydrogen/electrolyzer.lua | 10 +- techage/icta_controller/display.lua | 2 +- techage/init.lua | 10 +- techage/iron_age/meltingpot.lua | 2 + techage/items/electronic.lua | 7 +- techage/items/moreblocks.lua | 2 + techage/liquids/ta5_tank.lua | 2 +- techage/locale/techage.de.tr | 33 ++- techage/locale/template.txt | 22 +- techage/logic/sequencer2.lua | 14 +- techage/manuals/manual_ta1_DE.md | 6 - techage/manuals/manual_ta3_DE.md | 2 +- techage/manuals/manual_ta3_EN.md | 2 +- techage/manuals/manual_ta4_DE.md | 1 - techage/manuals/manual_ta4_EN.md | 1 - techage/manuals/manual_ta5_DE.md | 16 +- techage/manuals/manual_ta5_EN.md | 16 +- techage/manuals/ta4_lua_controller_EN.md | 4 +- techage/manuals/toc_DE.md | 1 - techage/move_controller/doorcontroller2.lua | 250 ++++++++++++++++--- techage/move_controller/movecontroller.lua | 37 +++ techage/power/power_terminal2.lua | 115 +++++++-- techage/solar/minicell.lua | 24 +- techage/ta3_power/axle2power.lua | 28 ++- techage/ta3_power/tiny_generator.lua | 22 ++ techage/teleport/teleport_pipe.lua | 4 +- techage/teleport/teleport_tube.lua | 4 +- techage/textures/techage_rack_and_pinion.png | Bin 0 -> 145 bytes 77 files changed, 1175 insertions(+), 534 deletions(-) create mode 100644 techage/textures/techage_rack_and_pinion.png diff --git a/autobahn/init.lua b/autobahn/init.lua index 6f529ba..ae06c6d 100644 --- a/autobahn/init.lua +++ b/autobahn/init.lua @@ -46,7 +46,7 @@ local function set_player_privs(player) meta:set_int("player_physics_locked", 1) if meta and physics then -- store the player privs default values - meta:set_int("autobahn_speed", physics.speed) + meta:set_float("autobahn_speed", physics.speed) -- set operator privs meta:set_int("autobahn_isactive", 1) physics.speed = 3.5 @@ -67,7 +67,7 @@ local function reset_player_privs(player) if meta and physics then -- restore the player privs default values meta:set_int("autobahn_isactive", 0) - physics.speed = meta:get_int("autobahn_speed") + physics.speed = meta:get_float("autobahn_speed") if physics.speed == 0 then physics.speed = 1 end -- delete stored default values meta:set_string("autobahn_speed", "") diff --git a/minecart/README.md b/minecart/README.md index 622ebaf..feb08af 100644 --- a/minecart/README.md +++ b/minecart/README.md @@ -43,7 +43,7 @@ The mod features are: - Extra Minecart privs for rail workers - Ingame documentation (German and English), based on the mod "doc" - API to register carts from other mods -- chat command '/mycart ' to output cart state and location +- chat command `/mycart ` to output cart state and location - Command interface for Techage (Lua and ICTA) and for Beduino Controllers @@ -74,50 +74,20 @@ Introduction at least every 16 nodes/meters) 9. Place a Minecart in front of the buffer and check whether it starts after the configured time -10. Check the cart state via the chat command: /mycart - '' is the cart number, or get a list of carts with /mycart +10. Check the cart state via the chat command: `/mycart ` + `` is the cart number, or get a list of carts with `/mycart` 11. Drop items into the Minecart and punch the cart to start it, or "sneak+click" the Minecart to get cart and items back 12. Dig the cart with 'sneak+click' (as usual). The items will be drop down. 13. To retrieve lost carts, use the chat command: /stopcart -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. -Cart Pusher ------------ +## Manual -Used to push a cart if the cart does not stop directly at a buffer. -The block has to be placed below the rail. +see [Wiki](https://github.com/joe7575/minecart/wiki) -Cart Speed / Speed Limit Signs ------------------------------- - -As before, the speed of the carts is also influenced by power rails. -Brake rails are irrelevant, the cart does not brake here. -The maximum speed is 8 m/s. This assumes a ratio of power rails -to normal rails of 1 to 4 on a flat section of rail. A rail section is a -series of rail nodes without a change of direction. After every curve / kink, -the speed for the next section of the route is newly determined, -taking into account the swing of the cart. This means that a cart can -roll over short rail sections without power rails. - -In order to additionally brake the cart at certain points -(at switches or in front of a buffer), speed limit signs can be placed -on the track. With these signs the speed can be reduced to 4, 2, or 1 m / s. -The "No speed limit" sign can be used to remove the speed limit. - -The speed limit signs must be placed next to the track so that they can -be read from the cart. This allows different speeds in each direction of travel. ## Command Interface @@ -159,14 +129,6 @@ The Cart Terminal has a Beduino command interface with the commands: -Migration to v2 ---------------- - -The way how carts are monitored and the cart speed is calculated has changed. -Therefore, it is necessary that all carts are repositioned and the -recording is repeated. -Rails and buffers are not affected and can be kept unchanged. - History ------- @@ -193,4 +155,5 @@ History Speed limit signs and cart terminal added 2021-09-02 V2.01 Chat command /stopcart added 2021-10-18 V2.02 Cart reproduction bug fixed -2023-01-04 V2.03 Techage and Beduino command interface added \ No newline at end of file +2023-01-04 V2.03 Techage and Beduino command interface added +2023-02-05 V2.04 New API functions added, EOL blanks removed \ No newline at end of file diff --git a/minecart/api.lua b/minecart/api.lua index e32d1b2..5438dfa 100644 --- a/minecart/api.lua +++ b/minecart/api.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- -- @@ -21,20 +21,20 @@ function minecart.is_cart_available(pos, param2, radius) return minecart.get_nodecart_nearby(pos, param2, radius) ~= nil or minecart.get_entitycart_nearby(pos, param2, radius) ~= nil -end +end -- Function returns true if a standing cart as node is avaliable function minecart.is_nodecart_available(pos, param2, radius) return minecart.get_nodecart_nearby(pos, param2, radius) ~= nil -end +end -- Function returns true if a standing cart as entity is avaliable function minecart.is_entitycart_available(pos, param2, radius) return minecart.get_entitycart_nearby(pos, param2, radius) ~= nil -end +end function minecart.punch_cart(pos, param2, radius, punch_dir) - local pos2, node = minecart.get_nodecart_nearby(pos, param2, radius) + local pos2, node = minecart.get_nodecart_nearby(pos, param2, radius) if pos2 then minecart.start_nodecart(pos2, node.name, nil, punch_dir) return true @@ -45,4 +45,39 @@ function minecart.punch_cart(pos, param2, radius, punch_dir) minecart.push_entitycart(entity, punch_dir) return true end -end \ No newline at end of file +end + +-------------------------------------------------------------------------------------------- +-- API functions for other mods to add/remove carts +-------------------------------------------------------------------------------------------- +function minecart.is_cart(name) + return minecart.tNodeNames[name] ~= nil +end + +-- Remove a cart, available as node +function minecart.remove_cart(pos) + local node = minecart.get_node_lvm(pos) + local cargo, owner, userID = minecart.remove_nodecart(pos, node) + minecart.monitoring_remove_cart(owner, userID) + local cartdef = {cargo = cargo, owner = owner, userID = userID} + return cartdef +end + +-- Place and start the cart +function minecart.place_and_start_cart(pos, node, cartdef, player) + local name = minecart.get_node_lvm(pos).name + if minecart.is_rail(pos, name) or minecart.is_cart(name) then + local vel = {x = 0, y = 0, z = 0} + local entity_name = minecart.tNodeNames[node.name] + local obj = minecart.add_entitycart(pos, node.name, entity_name, vel, + cartdef.cargo, cartdef.owner, cartdef.userID) + local entity = obj:get_luaentity() + minecart.monitoring_add_cart(cartdef.owner, cartdef.userID, pos, node.name, entity_name) + if player then + minecart.manage_attachment(player, entity, true) + end + minecart.start_entitycart(entity, pos, 0) + else + minecart.add_nodecart(pos, node.name, node.param2, cartdef.cargo, cartdef.owner, cartdef.userID, true) + end +end diff --git a/minecart/baselib.lua b/minecart/baselib.lua index 09fea93..3e38bd5 100644 --- a/minecart/baselib.lua +++ b/minecart/baselib.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- -- for lazy programmers @@ -142,7 +142,7 @@ end minetest.register_entity("minecart:marker", { initial_properties = { - visual = "upright_sprite", + visual = "upright_sprite", textures = {"minecart_marker_cube.png"}, use_texture_alpha = minecart.CLIP, physical = false, @@ -229,7 +229,7 @@ function minecart.manage_attachment(player, entity, get_on) return end player_api.player_attached[player_name] = get_on - + local obj = entity.object if get_on then player:set_attach(obj, "", {x=0, y=-4.5, z=-4}, {x=0, y=0, z=0}) @@ -254,10 +254,12 @@ function minecart.register_cart_names(node_name, entity_name, cart_type) minecart.tCartTypes[node_name] = cart_type end -function minecart.add_nodecart(pos, node_name, param2, cargo, owner, userID) +function minecart.add_nodecart(pos, node_name, param2, cargo, owner, userID, force) if pos and node_name and param2 and cargo and owner and userID then local pos2 - if not minecart.is_rail(pos) then + if force then + pos2 = pos + elseif not minecart.is_rail(pos) then pos2 = minetest.find_node_near(pos, 1, minecart.lRails) if not pos2 or not minecart.is_rail(pos2) then -- If no rail is around, use an available cart as new search center @@ -273,14 +275,14 @@ function minecart.add_nodecart(pos, node_name, param2, cargo, owner, userID) if pos2 then local node = minetest.get_node(pos2) local ndef = minetest.registered_nodes[node_name] - local rail = node.name minetest.swap_node(pos2, {name = node_name, param2 = param2}) local meta = M(pos2) - meta:set_string("removed_rail", rail) + meta:set_string("removed_rail", node.name) + meta:set_string("removed_rail_param2", node.param2) meta:set_string("owner", owner) meta:set_int("userID", userID) meta:set_string("infotext", owner .. ": " .. userID) - + if cargo and ndef.set_cargo then ndef.set_cargo(pos2, cargo) end @@ -295,7 +297,7 @@ end function minecart.add_entitycart(pos, node_name, entity_name, vel, cargo, owner, userID) local obj = minetest.add_entity(pos, entity_name) local objID = minecart.get_object_id(obj) - + if objID then local entity = obj:get_luaentity() entity.start_pos = pos @@ -312,7 +314,7 @@ end function minecart.start_entitycart(self, pos, facedir) local route = {} - + self.is_running = true self.arrival_time = 0 self.start_pos = minecart.get_buffer_pos(pos, self.owner) or minecart.get_next_buffer(pos, facedir) @@ -324,26 +326,33 @@ function minecart.start_entitycart(self, pos, facedir) -- If set the start waypoint will be deleted self.no_normal_start = self.start_pos == nil if self.driver == nil then - minecart.start_monitoring(self.owner, self.userID, pos, self.objID, + minecart.start_monitoring(self.owner, self.userID, pos, self.objID, route.checkpoints, route.junctions, self.cargo or {}) end end -function minecart.remove_nodecart(pos) - local node = minetest.get_node(pos) +function minecart.remove_nodecart(pos, node) + node = node or minetest.get_node(pos) local ndef = minetest.registered_nodes[node.name] local meta = M(pos) local rail = meta:get_string("removed_rail") + local param2 = meta:get_int("removed_rail_param2") if rail == "" then rail = "air" end local userID = meta:get_int("userID") local owner = meta:get_string("owner") meta:set_string("infotext", "") meta:set_string("formspec", "") local cargo = ndef.get_cargo and ndef.get_cargo(pos) or {} - minetest.swap_node(pos, {name = rail}) + minetest.swap_node(pos, {name = rail, param2 = param2}) return cargo, owner, userID -end - +end + +function minecart.is_usable_cart(pos, node) + -- cart needs a rail bwelow + local rail = M(pos):get_string("removed_rail") + return minecart.is_rail(pos, rail) +end + function minecart.node_to_entity(pos, node_name, entity_name) -- Remove node local cargo, owner, userID = minecart.remove_nodecart(pos) @@ -362,7 +371,7 @@ function minecart.entity_to_node(pos, entity) minetest.sound_stop(entity.sound_handle) entity.sound_handle = nil end - + local rot = entity.object:get_rotation() local dir = minetest.yaw_to_dir(rot.y) local facedir = minetest.dir_to_facedir(dir) @@ -400,6 +409,6 @@ function minecart.remove_entity(self, pos, player) minecart.add_node_to_player_inventory(pos, player, self.node_name or "minecart:cart") end minecart.stop_monitoring(self.owner, self.userID, pos) - minecart.stop_recording(self, pos) + minecart.stop_recording(self, pos) self.object:remove() end diff --git a/minecart/beduino.lua b/minecart/beduino.lua index 9ecd2fa..d58943f 100644 --- a/minecart/beduino.lua +++ b/minecart/beduino.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- local minecart_lib = [[ @@ -90,4 +90,4 @@ minetest.register_on_mods_loaded(function() vm16.register_ro_file("beduino", "lib/minecart.c", minecart_lib) vm16.register_ro_file("beduino", "demo/minecart.c", minecart_demo) end -end) \ No newline at end of file +end) diff --git a/minecart/doc.lua b/minecart/doc.lua index 2d294fc..0d23451 100644 --- a/minecart/doc.lua +++ b/minecart/doc.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- diff --git a/minecart/entitylib.lua b/minecart/entitylib.lua index 5c1cbd2..bb3f3f8 100644 --- a/minecart/entitylib.lua +++ b/minecart/entitylib.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end @@ -25,21 +25,25 @@ local player_ctrl = minecart.player_ctrl local tEntityNames = minecart.tEntityNames local function stop_cart(self, cart_pos) + local player self.is_running = false self.arrival_time = 0 - + if self.driver then - local player = minetest.get_player_by_name(self.driver) + player = minetest.get_player_by_name(self.driver) if player then - minecart.stop_recording(self, cart_pos) + minecart.stop_recording(self, cart_pos) minecart.manage_attachment(player, self, false) end end if not minecart.get_buffer_pos(cart_pos, self.owner) then - -- Probably somewhere in the pampas + -- Probably somewhere in the pampas minecart.delete_cart_waypoint(cart_pos) end minecart.entity_to_node(cart_pos, self) + if player then + player:set_pos(cart_pos) + end end local function get_ctrl(self, pos) @@ -50,20 +54,20 @@ end local function new_speed(self, new_dir) self.cart_speed = self.cart_speed or 0 local rail_speed = (self.waypoint.speed or 0) / 10 - + if rail_speed <= 0 then rail_speed = math.max(self.cart_speed + rail_speed, 0) elseif rail_speed <= self.cart_speed then rail_speed = math.max((self.cart_speed + rail_speed) / 2, 0) end - + -- Speed corrections if new_dir.y == 1 then if rail_speed < 1 then rail_speed = 0 end else if rail_speed < 0.4 then rail_speed = 0 end end - + self.cart_speed = rail_speed -- store for next cycle return rail_speed end @@ -82,7 +86,7 @@ local function running(self) facedir = minetest.dir_to_facedir(dir) end local cart_pos, wayp_pos, is_junction - + if self.reenter then -- through monitoring cart_pos = H2P(self.reenter[1]) -- pos correction on slopes @@ -120,14 +124,14 @@ local function running(self) stop_cart(self, wayp_pos) return end - + if is_junction then if self.is_recording then set_junctions(self, wayp_pos) end self.ctrl = nil end - + --print("running", LEN(self.junctions)) local dist = vector.distance(cart_pos, self.waypoint.cart_pos or self.waypoint.pos) local new_dir = dot2dir(self.waypoint.dot) @@ -138,7 +142,7 @@ local function running(self) self.speed_limit = minecart.get_speedlimit(wayp_pos, facedir) or self.speed_limit end new_speed = math.min(new_speed, self.speed_limit) - + local new_cart_pos, extra_cycle = minecart.get_current_cart_pos_correction( wayp_pos, facedir, dir.y, self.waypoint.dot) -- TODO: Why has self.waypoint no dot? if extra_cycle and not vector.equals(cart_pos, new_cart_pos) then @@ -147,13 +151,13 @@ local function running(self) dist = vector.distance(cart_pos, new_cart_pos) --print("extra_cycle", P2S(cart_pos), P2S(wayp_pos), P2S(new_cart_pos), new_speed) end - + -- Slope corrections --print("Slope corrections", P2S(new_dir), P2S(cart_pos)) if new_dir.y ~= 0 then cart_pos.y = cart_pos.y + 0.2 - end - + end + -- Calc velocity, rotation and arrival_time local yaw = minetest.dir_to_yaw(new_dir) local pitch = new_dir.y * math.pi/4 @@ -161,16 +165,16 @@ local function running(self) local vel = vector.multiply(new_dir, new_speed / ((new_dir.y ~= 0) and 1.41 or 1)) self.arrival_time = self.timebase + (dist / new_speed) -- needed for recording - self.curr_speed = new_speed + self.curr_speed = new_speed self.num_sections = (self.num_sections or 0) + 1 - + -- Got stuck somewhere if new_speed < 0.1 or dist < 0 then minetest.log("warning", "[Minecart] Got stuck somewhere " .. new_speed .. " " .. dist) stop_cart(self, wayp_pos) return end - + self.object:set_pos(cart_pos) self.object:set_rotation({x = pitch, y = yaw, z = 0}) self.object:set_velocity(vel) @@ -194,12 +198,12 @@ end local function on_step(self, dtime) self.timebase = (self.timebase or 0) + dtime - + if self.is_running then if self.arrival_time <= self.timebase then running(self) end - + if (self.sound_ttl or 0) <= self.timebase then play_sound(self) self.sound_ttl = self.timebase + 1.0 @@ -208,7 +212,7 @@ local function on_step(self, dtime) if self.sound_handle then minetest.sound_stop(self.sound_handle) self.sound_handle = nil - end + end end if self.driver then @@ -219,7 +223,7 @@ local function on_step(self, dtime) end if recording_junctions(self) then local pos = vector.round(self.object:get_pos()) - minecart.stop_recording(self, pos, true) + minecart.stop_recording(self, pos, true) local player = minetest.get_player_by_name(self.driver) minecart.manage_attachment(player, self, false) minecart.entity_to_node(pos, self) @@ -252,13 +256,13 @@ local function on_entitycard_punch(self, puncher, time_from_last_punch, tool_cap -- Dig cart if self.driver then -- remove cart as driver - minecart.stop_recording(self, pos, true) + minecart.stop_recording(self, pos, true) minecart.monitoring_remove_cart(self.owner, self.userID) minecart.remove_entity(self, pos, puncher) minecart.manage_attachment(puncher, self, false) else -- remove cart from outside - minecart.monitoring_remove_cart(self.owner, self.userID) + minecart.monitoring_remove_cart(self.owner, self.userID) minecart.remove_entity(self, pos, puncher) end end @@ -272,11 +276,11 @@ local function on_entitycard_punch(self, puncher, time_from_last_punch, tool_cap end local facedir = minetest.dir_to_facedir(dir or {x=0, y=0, z=0}) minecart.start_entitycart(self, pos, facedir or 0) - minecart.start_recording(self, pos) + minecart.start_recording(self, pos) end end end - + -- Player get on / off local function on_entitycard_rightclick(self, clicker) if clicker and clicker:is_player() and self.driver_allowed then @@ -284,13 +288,13 @@ local function on_entitycard_rightclick(self, clicker) if self.driver then -- get off local pos = vector.round(self.object:get_pos()) - minecart.stop_recording(self, pos, true) + minecart.stop_recording(self, pos, true) minecart.manage_attachment(clicker, self, false) minecart.entity_to_node(pos, self) else -- get on local pos = vector.round(self.object:get_pos()) - minecart.stop_recording(self, pos, true) + minecart.stop_recording(self, pos, true) minecart.manage_attachment(clicker, self, true) end end @@ -312,7 +316,7 @@ function minecart.get_entitycart_nearby(pos, param2, radius) return entity end end - end + end end function minecart.push_entitycart(self, punch_dir) @@ -333,11 +337,11 @@ function minecart.register_cart_entity(entity_name, node_name, cart_type, entity entity_def.on_step = on_step entity_def.on_rightclick = on_entitycard_rightclick entity_def.on_detach_child = on_entitycard_detach_child - + entity_def.owner = nil entity_def.driver = nil entity_def.cargo = {} - + minetest.register_entity(entity_name, entity_def) -- register node for punching minecart.register_cart_names(node_name, entity_name, cart_type) diff --git a/minecart/hopper.lua b/minecart/hopper.lua index 7b7fbbf..12c6e76 100644 --- a/minecart/hopper.lua +++ b/minecart/hopper.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- local NUM_ITEMS = 4 @@ -112,7 +112,7 @@ minetest.register_node("minecart:hopper", { 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()) @@ -130,7 +130,7 @@ minetest.register_node("minecart:hopper", { 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 @@ -145,13 +145,13 @@ minetest.register_node("minecart:hopper", { 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, - + paramtype = "light", sunlight_propagates = true, paramtype2 = "facedir", diff --git a/minecart/hopperlib.lua b/minecart/hopperlib.lua index d04ad05..45a8113 100644 --- a/minecart/hopperlib.lua +++ b/minecart/hopperlib.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- -- for lazy programmers @@ -43,7 +43,7 @@ function minecart.take_items(pos, param2, num) 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 def.take_listname and (not def.allow_take or def.allow_take(npos, nil, owner)) then return minecart.inv_take_items(inv, def.take_listname, num) elseif def and def.take_item then @@ -61,7 +61,7 @@ function minecart.put_items(pos, param2, stack) 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 def.put_listname 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 @@ -93,7 +93,7 @@ function minecart.untake_items(pos, param2, stack) end local def = RegisteredInventories[node.name] local inv = minetest.get_inventory({type="node", pos=npos}) - + if def and inv and def.take_listname then return inv:add_item(def.take_listname, stack) elseif def and def.untake_item then @@ -128,14 +128,14 @@ minecart.register_inventory({"minecart:hopper"}, { allow_inventory_put = function(pos, stack, player_name) local owner = M(pos):get_string("owner") return owner == player_name - end, + end, listname = "main", }, take = { allow_inventory_take = function(pos, stack, player_name) local owner = M(pos):get_string("owner") return owner == player_name - end, + end, listname = "main", }, }) diff --git a/minecart/init.lua b/minecart/init.lua index e30d189..6c09b98 100644 --- a/minecart/init.lua +++ b/minecart/init.lua @@ -13,7 +13,7 @@ minecart = {} -- Version for compatibility checks, see readme.md/history -minecart.version = 2.03 +minecart.version = 2.04 minecart.hopper_enabled = minetest.settings:get_bool("minecart_hopper_enabled") ~= false minecart.teleport_enabled = minetest.settings:get_bool("minecart_teleport_enabled") == true diff --git a/minecart/locale/minecart.de.tr b/minecart/locale/minecart.de.tr index fdba00c..f3e2d66 100644 --- a/minecart/locale/minecart.de.tr +++ b/minecart/locale/minecart.de.tr @@ -3,6 +3,7 @@ Station name=Stationsname Waiting time/sec=Wartezeit/s connected to=verbunden mit Not connected!=Nicht verbunden! +Minecart Railway Buffer=Minecart Prellbock Summary=Zusammenfassung 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 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). @@ -27,21 +28,20 @@ Minecart Cart=Wagen Minecart Speed Signs=Geschwindigkeitsbegrenzungszeichen If several carts are running on one route,@nit can happen that a buffer position is already occupied and one cart therefore stops earlier.@nIn this case, the cart pusher is used to push the cart towards the buffer again.@nThis block must be placed under the rail at a distance of 2 m in front of the buffer.=Wenn mehrere Wagen auf einer Route fahren, kann es vorkommen,@ndass eine Prellbock Position bereits belegt ist und ein Wagen daher früher anhält.@nDer Cart Anschieber dient in diesem Fall dazu, die Wagen wieder in Richtung Prellbock anzuschieben.@nDieser Block muss unter der Schiene mit 2 m Abstand vor dem Prellbock platziert werden. Limit the cart speed with speed limit signs.@n@nAs before, the speed of the carts is also influenced by power rails.@nBrake rails are irrelevant, the cart does not brake here.@nThe maximum speed is 8 m/s. This assumes a ratio of power rails@nto normal rails of 1 to 4 on a flat section of rail. A rail section is a@nseries of rail nodes without a change of direction. After every curve / kink,@nthe speed for the next section of the route is newly determined,@ntaking into account the swing of the cart. This means that a cart can@nroll over short rail sections without power rails.@n@nIn order to additionally brake the cart at certain points@n(at switches or in front of a buffer), speed limit signs can be placed@non the track. With these signs the speed can be reduced to 4, 2, or 1 m / s.@nThe "No speed limit" sign can be used to remove the speed limit.@n@nThe speed limit signs must be placed next to the track so that they can@nbe read from the cart. This allows different speeds in each direction of travel.=Begrenze die Geschwindigkeit der Wagen mit Geschwindigkeitsbegrenzungszeichen@n@nDie Geschwindigkeit der Carts wird wie bisher auch über "power rails" beeinflusst. "Brake rails" sind ohne Bedeutung, das Cart bremst hier nicht. Die maximale Geschwindigkeit beträgt 8 m/s. Dies setzt eine Verhältnis von "power rails" zu "normal rails" von 1 zu 4 auf einem ebenen Streckenabschnitt voraus. Ein Streckenabschnitt ist dabei ein Reihe von Schienenblöcken ohne Richtungsänderung. Nach jeder Kurve/Knick wird die Geschwindigkeit für den nächsten Streckenabschnitt neu bestimmt, wobei hier der Schwung des Carts mit berücksichtigt wird. So kann ein Cart auch über kurze Streckenabschnitt ohne "power rails" rollen.@n@nUm das Cart zusätzlich an bestimmten Stellen abzubremsen (an Weichen oder vor einen Puffer), können Geschwindigkeitsbegrenzungszeichen an der Strecke platziert werden. Durch diese Zeichen kann die Geschwindigkeit auf 4, 2, oder 1 m/s reduziert werden. Durch das Aufhebungszeichen kann die Geschwindigkeitsbegrenzung wieder aufgehoben werden.@n@nDie Geschwindigkeitsbegrenzungszeichen müssen so neben die Strecke platziert werden, dass sie vom Cart ablesbar sind. Dies erlaubt damit unterschiedliche Geschwindigkeiten pro Fahrtrichtung. -Minecart Railway Buffer=Minecart Prellbock Minecart Hopper=Minecart Hopper -Minecart Landmark=Minecart Meilenstein -Cart Pusher=Wagen Anschieber Minecart (Sneak+Click to pick up)=Minecart (Shift+Klick zum Entfernen des Carts) Output cart state and position, or a list of carts, if no cart number is given.=Gibt Status und Position des Wagens, oder eine Liste aller Wagen aus, wenn keine Wagennummer angegeben ist. List of carts=Liste aller Wagen -Stop amd return a missing/running cart.=Stoppe und hole einen vermissten Wagen zurück. +Stop and return/drop a missing/running cart.=Stoppe und hole einen vermissten Wagen zurück. Cart=Wagen -stopped=gestoppt +dropped=fallen gelassen is not existing!=existiert nicht! Enter cart number=Gebe Cart Nummer ein Save=Speichern [minecart] Area is protected!=[minecart] Bereich ist geschützt! Allow to dig/place rails in Minecart Landmark areas=Erlaubt dir, Schienen in Meilensteinbereichen zu setzen/zu entfernen +Minecart Landmark=Minecart Meilenstein +Cart Pusher=Wagen Anschieber left=links right=rechts straight=geradeaus @@ -49,6 +49,7 @@ Recording=Aufzeichnung speed=Tempo next junction=nächste Weiche Travel time=Fahrzeit +[minecart] Recording canceled!= [minecart] Route stored!=[minecart] Strecke gespeichert [minecart] Speed @= %u m/s, Time @= %u s, Route length @= %u m=[minecart] Geschw. @= %u m/s, Zeit @= %u s, Routenlänge @= %u m [minecart] Your route is too short to record!=[minecart] Deine Strecke ist zu kurz für eine Aufzeichnung! @@ -58,3 +59,9 @@ Speed "4"=Tempo "4" No speed limit=Keine Geschwindigkeitsbegrenzung Cart List=Cart Liste Cart Terminal=Cart Terminal + + +##### not used anymore ##### + +Stop amd return a missing/running cart.=Stoppe und hole einen vermissten Wagen zurück. +stopped=gestoppt diff --git a/minecart/locale/template.txt b/minecart/locale/template.txt index 45ebd43..14970ac 100644 --- a/minecart/locale/template.txt +++ b/minecart/locale/template.txt @@ -3,6 +3,7 @@ Station name= Waiting time/sec= connected to= Not connected!= +Minecart Railway Buffer= Summary= 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).= @@ -27,21 +28,20 @@ Minecart Cart= Minecart Speed Signs= If several carts are running on one route,@nit can happen that a buffer position is already occupied and one cart therefore stops earlier.@nIn this case, the cart pusher is used to push the cart towards the buffer again.@nThis block must be placed under the rail at a distance of 2 m in front of the buffer.= Limit the cart speed with speed limit signs.@n@nAs before, the speed of the carts is also influenced by power rails.@nBrake rails are irrelevant, the cart does not brake here.@nThe maximum speed is 8 m/s. This assumes a ratio of power rails@nto normal rails of 1 to 4 on a flat section of rail. A rail section is a@nseries of rail nodes without a change of direction. After every curve / kink,@nthe speed for the next section of the route is newly determined,@ntaking into account the swing of the cart. This means that a cart can@nroll over short rail sections without power rails.@n@nIn order to additionally brake the cart at certain points@n(at switches or in front of a buffer), speed limit signs can be placed@non the track. With these signs the speed can be reduced to 4, 2, or 1 m / s.@nThe "No speed limit" sign can be used to remove the speed limit.@n@nThe speed limit signs must be placed next to the track so that they can@nbe read from the cart. This allows different speeds in each direction of travel.= -Minecart Railway Buffer= Minecart Hopper= -Minecart Landmark= -Cart Pusher= Minecart (Sneak+Click to pick up)= Output cart state and position, or a list of carts, if no cart number is given.= List of carts= -Stop amd return a missing/running cart.= +Stop and return/drop a missing/running cart.= Cart= -stopped= +dropped= is not existing!= Enter cart number= Save= [minecart] Area is protected!= Allow to dig/place rails in Minecart Landmark areas= +Minecart Landmark= +Cart Pusher= left= right= straight= @@ -49,6 +49,7 @@ Recording= speed= next junction= Travel time= +[minecart] Recording canceled!= [minecart] Route stored!= [minecart] Speed @= %u m/s, Time @= %u s, Route length @= %u m= [minecart] Your route is too short to record!= diff --git a/minecart/minecart.lua b/minecart/minecart.lua index 1237019..210a426 100644 --- a/minecart/minecart.lua +++ b/minecart/minecart.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- local S = minecart.S @@ -16,7 +16,7 @@ local M = minetest.get_meta minetest.register_node("minecart:cart", { description = S("Minecart (Sneak+Click to pick up)"), tiles = { - -- up, down, right, left, back, front + -- up, down, right, left, back, front "carts_cart_top.png^minecart_appl_cart_top.png", "carts_cart_top.png", "carts_cart_side.png^minecart_logo.png", @@ -49,7 +49,7 @@ minetest.register_node("minecart:cart", { groups = {cracky = 2, crumbly = 2, choppy = 2}, node_placement_prediction = "", diggable = false, - + on_place = minecart.on_nodecart_place, on_punch = minecart.on_nodecart_punch, @@ -57,20 +57,22 @@ minetest.register_node("minecart:cart", { if clicker and clicker:is_player() then if M(pos):get_int("userID") ~= 0 then -- enter the cart - local object = minecart.node_to_entity(pos, "minecart:cart", "minecart:cart_entity") - minecart.manage_attachment(clicker, object:get_luaentity(), true) - else + if minecart.is_usable_cart(pos, node) then + local object = minecart.node_to_entity(pos, "minecart:cart", "minecart:cart_entity") + minecart.manage_attachment(clicker, object:get_luaentity(), true) + end + else minecart.show_formspec(pos, clicker) end end end, - + set_cargo = function(pos, data) for _,item in ipairs(data or {}) do minetest.add_item(pos, ItemStack(item)) end end, - + get_cargo = function(pos) local data = {} for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do diff --git a/minecart/mods_support.lua b/minecart/mods_support.lua index cebb9ea..178c7a9 100644 --- a/minecart/mods_support.lua +++ b/minecart/mods_support.lua @@ -7,9 +7,9 @@ MIT See license.txt for more information - + Wrapper functions to get hopper support for other mods - + ]]-- -- for lazy programmers @@ -19,7 +19,7 @@ local CacheForFuelNodeNames = {} local function is_fuel(stack) local name = stack:get_name() - if CacheForFuelNodeNames[name] then + if CacheForFuelNodeNames[name] then return true end if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then @@ -28,6 +28,19 @@ local function is_fuel(stack) return CacheForFuelNodeNames[name] end +------------------------------------------------------------------------------ +-- Signs Bot +------------------------------------------------------------------------------ + +minecart.register_inventory({"signs_bot:box"}, { + put = { + listname = "main", + }, + take = { + listname = "main", + }, +}) + ------------------------------------------------------------------------------ -- default ------------------------------------------------------------------------------ @@ -46,14 +59,14 @@ minecart.register_inventory({"default:chest_locked", "default:chest_locked_open" allow_inventory_put = function(pos, stack, player_name) local owner = M(pos):get_string("owner") return owner == player_name - end, + end, listname = "main", }, take = { allow_inventory_take = function(pos, stack, player_name) local owner = M(pos):get_string("owner") return owner == player_name - end, + end, listname = "main", }, }) @@ -68,8 +81,8 @@ minecart.register_inventory({"default:furnace", "default:furnace_active"}, { minetest.get_node_timer(pos):start(1.0) if leftover:get_count() > 0 then return leftover - end - end, + end + end, }, take = { -- fuel can't be taken @@ -108,8 +121,8 @@ minecart.register_inventory({"digtron:combined_storage"}, { local leftover = inv:add_item(listname, stack) if leftover:get_count() > 0 then return leftover - end - end, + end + end, }, take = { -- fuel can't be taken diff --git a/minecart/monitoring.lua b/minecart/monitoring.lua index c3e0242..121b487 100644 --- a/minecart/monitoring.lua +++ b/minecart/monitoring.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- -- for lazy programmers @@ -49,7 +49,7 @@ end local function zombie_to_entity(pos, cart, checkpoint) local vel = {x = 0, y = 0, z = 0} - local obj = minecart.add_entitycart(pos, cart.node_name, cart.entity_name, + local obj = minecart.add_entitycart(pos, cart.node_name, cart.entity_name, vel, cart.cargo, cart.owner, cart.userID) if obj then local entity = obj:get_luaentity() @@ -72,7 +72,7 @@ local function get_checkpoint(cart) end -- Function returns the cart state ("running" / "stopped") and --- the station name or position string, or if cart is running, +-- the station name or position string, or if cart is running, -- the distance to the query_pos. local function get_cart_state_and_loc(name, userID, query_pos) if tCartsOnRail[name] and tCartsOnRail[name][userID] then @@ -120,7 +120,7 @@ end local function logging(cart, err) local s = string.format("[Minecart] Cart %s/%u %s!", cart.owner, cart.userID, err) minetest.log("warning", s) -end +end -- check cart data local function valid_cart(cart) @@ -140,7 +140,7 @@ end local function monitoring(cycle) local cart = pop(cycle) - + -- All running cars while cart do if valid_cart(cart) then @@ -198,7 +198,7 @@ function minecart.monitoring_add_cart(owner, userID, pos, node_name, entity_name } minecart.store_carts() end - + function minecart.start_monitoring(owner, userID, pos, objID, checkpoints, junctions, cargo) --print("start_monitoring", owner, userID) if tCartsOnRail[owner] and tCartsOnRail[owner][userID] then @@ -242,7 +242,7 @@ end function minecart.monitoring_valid_cart(owner, userID, pos, node_name) if tCartsOnRail[owner] and tCartsOnRail[owner][userID] and tCartsOnRail[owner][userID].pos then - return vector.equals(tCartsOnRail[owner][userID].pos, pos) and + return vector.equals(tCartsOnRail[owner][userID].pos, pos) and tCartsOnRail[owner][userID].node_name == node_name end end @@ -271,7 +271,7 @@ minetest.register_chatcommand("mycart", { func = function(owner, param) local userID = tonumber(param) local query_pos = minetest.get_player_by_name(owner):get_pos() - + if userID then return true, get_cart_info(owner, userID, query_pos) elseif tCartsOnRail[owner] then @@ -295,12 +295,12 @@ minetest.register_chatcommand("stopcart", { local data = minecart.get_cart_monitoring_data(owner, userID) if data and data.objID then local entity = minetest.luaentities[data.objID] - --print("stopcart", userID, data.pos, data.objID, entity) + --print("stopcart", userID, data.pos, data.objID, entity) if data.objID == 0 then -- Cart as node - if data.pos then + if data.pos then local meta = M(data.pos) - if owner == meta:get_string("owner") and userID == meta:get_int("userID") then + if owner == meta:get_string("owner") and userID == meta:get_int("userID") then minecart.remove_nodecart(data.pos) end end @@ -340,17 +340,17 @@ end function minecart.get_cart_list(pos, name) local userIDs = {} local carts = {} - + for userID, cart in pairs(tCartsOnRail[name] or {}) do userIDs[#userIDs + 1] = userID end - + table.sort(userIDs, function(a,b) return a < b end) - + for _, userID in ipairs(userIDs) do carts[#carts + 1] = get_cart_info(name, userID, pos) end - + return table.concat(carts, "\n") end @@ -366,9 +366,9 @@ minetest.register_on_mods_loaded(function() default = "", }, { - type = "label", - name = "lbl", - label = "Read state from one of your carts", + type = "label", + name = "lbl", + label = "Read state from one of your carts", }, }, button = function(data, environ) -- default button label @@ -396,9 +396,9 @@ minetest.register_on_mods_loaded(function() default = "", }, { - type = "label", - name = "lbl", - label = "Read location from one of your carts", + type = "label", + name = "lbl", + label = "Read location from one of your carts", }, }, button = function(data, environ) -- default button label @@ -417,7 +417,7 @@ minetest.register_on_mods_loaded(function() end, }) techage.lua_ctlr.register_function("cart_state", { - cmnd = function(self, num) + cmnd = function(self, num) num = tonumber(num) or 0 return minecart.cmnd_cart_state(self.meta.owner, num) end, @@ -427,7 +427,7 @@ minetest.register_on_mods_loaded(function() ' example: sts = $cart_state(2)' }) techage.lua_ctlr.register_function("cart_location", { - cmnd = function(self, num) + cmnd = function(self, num) num = tonumber(num) or 0 return minecart.cmnd_cart_location(self.meta.owner, num, self.meta.pos) end, diff --git a/minecart/nodelib.lua b/minecart/nodelib.lua index 098fc73..8a8bf52 100644 --- a/minecart/nodelib.lua +++ b/minecart/nodelib.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- -- for lazy programmers @@ -16,7 +16,7 @@ local S = minecart.S local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end local S2P = minetest.string_to_pos -function minecart.get_nodecart_nearby(pos, param2, radius) +function minecart.get_nodecart_nearby(pos, param2, radius) local pos2 = param2 and vector.add(pos, minecart.param2_to_dir(param2)) or pos local pos3 = minetest.find_node_near(pos2, radius or 0.5, minecart.lCartNodeNames, true) if pos3 then @@ -35,7 +35,7 @@ function minecart.start_nodecart(pos, node_name, puncher, punch_dir) if owner ~= "" and userID ~= "" and entity_name then minecart.monitoring_add_cart(owner, userID, pos, node_name, entity_name) else - M(pos):set_string("infotext", + M(pos):set_string("infotext", minetest.get_color_escape_sequence("#FFFF00") .. owner .. ": 0") return end @@ -48,7 +48,7 @@ function minecart.start_nodecart(pos, node_name, puncher, punch_dir) if obj then local entity = obj:get_luaentity() local facedir - + if puncher then local yaw = puncher:get_look_horizontal() entity.object:set_rotation({x = 0, y = yaw, z = 0}) @@ -72,7 +72,7 @@ function minecart.show_formspec(pos, clicker) "size[4,3]" .. "label[0,0;" .. S("Enter cart number") .. ":]" .. "field[1,1;3,1;userID;;]" .. - "button_exit[1,2;2,1;exit;" .. S("Save") .. "]") + "button_exit[1,2;2,1;exit;" .. S("Save") .. "]") end end @@ -81,7 +81,7 @@ function minecart.on_nodecart_place(itemstack, placer, pointed_thing) local node_name = itemstack:get_name() local param2 = minetest.dir_to_facedir(placer:get_look_dir()) local owner = placer:get_player_name() - + -- Add node if minecart.is_rail(pointed_thing.under) then minecart.add_nodecart(pointed_thing.under, node_name, param2, {}, owner, 0) @@ -102,20 +102,19 @@ function minecart.on_nodecart_place(itemstack, placer, pointed_thing) and creative.is_enabled_for(placer:get_player_name())) then itemstack:take_item() end - + return itemstack end -- Start the node cart (or dig by shift+leftclick) function minecart.on_nodecart_punch(pos, node, puncher, pointed_thing) - --print("on_nodecart_punch") local owner = M(pos):get_string("owner") - local userID = M(pos):get_int("userID") + local rail = M(pos):get_string("removed_rail") if minecart.is_owner(puncher, owner) then - if puncher:get_player_control().sneak then + if puncher:get_player_control().sneak or not minecart.is_rail(pos, rail) then local ndef = minetest.registered_nodes[node.name] if not ndef.has_cargo or not ndef.has_cargo(pos) then - minecart.remove_nodecart(pos) + local _, owner, userID = minecart.remove_nodecart(pos, node) minecart.add_node_to_player_inventory(pos, puncher, node.name) minecart.monitoring_remove_cart(owner, userID) end @@ -134,7 +133,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) local userID = tonumber(fields.userID) or 0 if minecart.userID_available(owner, userID) then M(cart_pos):set_int("userID", userID) - M(cart_pos):set_string("infotext", + M(cart_pos):set_string("infotext", minetest.get_color_escape_sequence("#FFFF00") .. player:get_player_name() .. ": " .. userID) local node = minetest.get_node(cart_pos) diff --git a/minecart/protection.lua b/minecart/protection.lua index 1df495f..527d72a 100644 --- a/minecart/protection.lua +++ b/minecart/protection.lua @@ -3,11 +3,11 @@ Minecart ======== - Copyright (C) 2019-2021 Joachim Stolberg + Copyright (C) 2019-2023 Joachim Stolberg MIT See license.txt for more information - + ]]-- local S = minecart.S @@ -77,7 +77,7 @@ minetest.register_node("minecart:landmark", { return true end end, - + can_dig = function(pos, digger) local meta = minetest.get_meta(pos) if meta:get_string("owner") == digger:get_player_name() then @@ -86,17 +86,19 @@ minetest.register_node("minecart:landmark", { if minetest.check_player_privs(digger:get_player_name(), "minecart") then return true 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")..")") return false end, - + on_punch = function(pos, node, puncher, pointed_thing) minecart.set_land_marker(pos, RANGE, 20) end, - - paramtype2 = "facedir", + + paramtype = "light", sunlight_propagates = true, + paramtype2 = "facedir", + use_texture_alpha = minecart.CLIP, groups = {cracky = 3, stone = 1}, is_ground_content = false, sounds = default.node_sound_stone_defaults(), @@ -135,7 +137,10 @@ minetest.register_node("minecart:ballast_slope", { type = "fixed", fixed = {-8/16, -8/16, -8/16, 8/16, 8/16, 8/16}, }, + paramtype = "light", + sunlight_propagates = true, paramtype2 = "facedir", + use_texture_alpha = minecart.CLIP, groups = {crumbly = 1, cracky = 3}, sounds = default.node_sound_stone_defaults(), }) @@ -157,7 +162,10 @@ minetest.register_node("minecart:ballast_ramp", { type = "fixed", fixed = {-8/16, -8/16, -8/16, 8/16, 8/16, 8/16}, }, + paramtype = "light", + sunlight_propagates = true, paramtype2 = "facedir", + use_texture_alpha = minecart.CLIP, groups = {crumbly = 1, cracky = 3}, sounds = default.node_sound_stone_defaults(), }) diff --git a/minecart/pusher.lua b/minecart/pusher.lua index bc49ad5..971eabc 100644 --- a/minecart/pusher.lua +++ b/minecart/pusher.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- -- for lazy programmers diff --git a/minecart/rails.lua b/minecart/rails.lua index 0162531..5311ba5 100644 --- a/minecart/rails.lua +++ b/minecart/rails.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- -- for lazy programmers @@ -22,9 +22,9 @@ local SLOWDOWN = 0.3 local MAX_NODES = 100 --waypoint = { --- dot = travel direction, --- pos = destination pos, --- speed = 10 times the section speed (as int), +-- dot = travel direction, +-- pos = destination pos, +-- speed = 10 times the section speed (as int), -- limit = 10 times the speed limit (as int), --} -- @@ -57,8 +57,8 @@ local tRailsExt = { } local tSigns = { - ["minecart:speed1"] = 1, - ["minecart:speed2"] = 2, + ["minecart:speed1"] = 1, + ["minecart:speed2"] = 2, ["minecart:speed4"] = 4, ["minecart:speed8"] = 8, } @@ -123,7 +123,7 @@ end local function get_metadata(pos) local hash = P2H(pos) - if tWaypoints[hash] then + if tWaypoints[hash] then return tWaypoints[hash] end local s = M(pos):get_string("waypoints") @@ -175,8 +175,8 @@ end ------------------------------------------------------------------------------- local function check_right(pos, facedir) local fdr = (facedir + 1) % 4 -- right - local new_pos = vector.add(pos, facedir2dir(fdr)) - + local new_pos = vector.add(pos, facedir2dir(fdr)) + local name = get_node_lvm(new_pos).name if tRailsExt[name] or tSigns[name] then return true @@ -189,8 +189,8 @@ end local function check_left(pos, facedir) local fdl = (facedir + 3) % 4 -- left - local new_pos = vector.add(pos, facedir2dir(fdl)) - + local new_pos = vector.add(pos, facedir2dir(fdl)) + local name = get_node_lvm(new_pos).name if tRailsExt[name] or tSigns[name] then return true @@ -202,7 +202,7 @@ local function check_left(pos, facedir) end local function get_next_pos(pos, facedir, y) - local new_pos = vector.add(pos, facedir2dir(facedir)) + local new_pos = vector.add(pos, facedir2dir(facedir)) new_pos.y = new_pos.y + y local name = get_node_lvm(new_pos).name return tRailsExt[name] ~= nil, new_pos, tRailsPower[name] or 0 @@ -225,7 +225,7 @@ local function find_next_waypoint(pos, facedir, y) local name = get_node_lvm(pos).name local speed = tRailsPower[name] or 0 local is_rail, new_pos, _speed - + while cnt < MAX_NODES do is_rail, new_pos, _speed = get_next_pos(pos, facedir, y) speed = speed + _speed @@ -249,8 +249,8 @@ end -- find_all_next_waypoints ------------------------------------------------------------------------------- local function check_front_up_down(pos, facedir) - local new_pos = vector.add(pos, facedir2dir(facedir)) - + local new_pos = vector.add(pos, facedir2dir(facedir)) + if tRailsExt[get_node_lvm(new_pos).name] then return 0 end @@ -278,11 +278,11 @@ end local function recalc_speed(num_pow_rails, pos1, pos2, y) local num_norm_rails = vector.distance(pos1, pos2) - num_pow_rails local ratio, speed - + if y ~= 0 then num_norm_rails = math.floor(num_norm_rails / 1.41 + 0.5) end - + if y ~= -1 then if num_pow_rails == 0 then return num_norm_rails * -SLOWDOWN @@ -293,7 +293,7 @@ local function recalc_speed(num_pow_rails, pos1, pos2, y) else ratio = 3 + num_norm_rails * SLOWDOWN + num_pow_rails end - + if y == 1 then speed = 7 - ratio elseif y == -1 then @@ -301,14 +301,14 @@ local function recalc_speed(num_pow_rails, pos1, pos2, y) else speed = 11 - ratio end - + return minecart.range(speed, 0, 8) -end +end local function find_all_next_waypoints(pos) local wp = {} local dots = {} - + for facedir = 0,3 do local y = check_front_up_down(pos, facedir) if y then @@ -319,7 +319,7 @@ local function find_all_next_waypoints(pos) wp[facedir] = {dot = dot, pos = new_pos, speed = speed, is_ramp = is_ramp} end end - + return wp end @@ -331,7 +331,7 @@ local function ramp_correction(pos, wp, facedir) if wp.is_ramp or pos.y < wp.pos.y then -- ramp detection local dir = facedir2dir(facedir) local pos = wp.pos - + wp.cart_pos = { x = pos.x - dir.x / 2, y = pos.y, @@ -339,7 +339,7 @@ local function ramp_correction(pos, wp, facedir) elseif pos.y > wp.pos.y then local dir = facedir2dir(facedir) local pos = wp.pos - + wp.cart_pos = { x = pos.x + dir.x / 2, y = pos.y, @@ -350,23 +350,23 @@ end -- Returns waypoint and is_junction function minecart.get_waypoint(pos, facedir, ctrl, uturn) - local t = get_metadata(pos) + local t = get_metadata(pos) if not t then t = find_all_next_waypoints(pos) set_metadata(pos, t) end - + local left = (facedir + 3) % 4 local right = (facedir + 1) % 4 local back = (facedir + 2) % 4 - + if ctrl.right and t[right] then return t[right], t[facedir] ~= nil or t[left] ~= nil end if ctrl.left and t[left] then return t[left] , t[facedir] ~= nil or t[right] ~= nil end - + if t[facedir] then return ramp_correction(pos, t[facedir], facedir), false end if t[right] then return ramp_correction(pos, t[right], right), false end if t[left] then return ramp_correction(pos, t[left], left), false end - + if uturn and t[back] then return t[back], false end end @@ -389,11 +389,11 @@ local function delete_next_metadata(pos, facedir, y) if not is_rail then return end - + if has_metadata(new_pos) then del_metadata(new_pos) end - + pos = new_pos cnt = cnt + 1 end @@ -408,27 +408,27 @@ function minecart.delete_waypoint(pos) delete_counterpart_metadata(pos, wp) return end - + for facedir = 0,3 do local y = check_front_up_down(pos, facedir) if y then - local new_pos = vector.add(pos, facedir2dir(facedir)) + local new_pos = vector.add(pos, facedir2dir(facedir)) new_pos.y = new_pos.y + y if has_metadata(new_pos) then local wp = get_metadata(new_pos) delete_counterpart_metadata(new_pos, wp) else - delete_next_metadata(pos, facedir, y) + delete_next_metadata(pos, facedir, y) end end end -end +end ------------------------------------------------------------------------------- -- find next buffer (needed as starting position) ------------------------------------------------------------------------------- local function get_next_waypoints(pos) - local t = get_metadata(pos) + local t = get_metadata(pos) if not t then t = find_all_next_waypoints(pos) end @@ -439,7 +439,7 @@ local function get_next_pos_and_facedir(waypoints, facedir) local cnt = 0 local newpos, newfacedir facedir = (facedir + 2) % 4 -- opposite dir - + for i = 0, 3 do if waypoints[i] then cnt = cnt + 1 @@ -449,7 +449,7 @@ local function get_next_pos_and_facedir(waypoints, facedir) end end end - + -- no junction and valid facedir if cnt < 3 and newfacedir then return newpos, newfacedir @@ -493,13 +493,13 @@ carts:register_rail("minecart:powerrail", { groups = carts:get_rail_groups({not_in_creative_inventory = 1}), drop = "carts:powerrail", }, {}) - + for name,_ in pairs(tRails) do minetest.override_item(name, { after_destruct = minecart.delete_waypoint, after_place_node = minecart.delete_waypoint, }) -end +end ------------------------------------------------------------------------------- -- API functions @@ -509,7 +509,7 @@ function minecart.get_current_cart_pos_correction(curr_pos, curr_fd, curr_y, new if new_dot then local new_y = (new_dot % 4) - 1 local new_fd = math.floor(new_dot / 4) - + if curr_y == -1 or new_y == -1 then local new_fd = math.floor(new_dot / 4) local dir = facedir2dir(new_fd) @@ -537,14 +537,14 @@ end -- Called by carts, returns the speed value or nil function minecart.get_speedlimit(pos, facedir) local fd = (facedir + 1) % 4 -- right - local new_pos = vector.add(pos, facedir2dir(fd)) + local new_pos = vector.add(pos, facedir2dir(fd)) local node = get_node_lvm(new_pos) if tSigns[node.name] and node.param2 == facedir then return tSigns[node.name] end - + fd = (facedir + 3) % 4 -- left - new_pos = vector.add(pos, facedir2dir(fd)) + new_pos = vector.add(pos, facedir2dir(fd)) node = get_node_lvm(new_pos) if tSigns[node.name] and node.param2 == facedir then return tSigns[node.name] @@ -555,25 +555,25 @@ end function minecart.delete_cart_waypoint(pos) del_metadata(pos) end - + -- Called by signs, to delete the rail waypoints nearby -function minecart.delete_signs_waypoint(pos) +function minecart.delete_signs_waypoint(pos) local node = minetest.get_node(pos) local facedir = (node.param2 + 1) % 4 -- right - local new_pos = vector.add(pos, facedir2dir(facedir)) + local new_pos = vector.add(pos, facedir2dir(facedir)) if tRailsExt[get_node_lvm(new_pos).name] then minecart.delete_waypoint(new_pos) end - + facedir = (node.param2 + 3) % 4 -- left - new_pos = vector.add(pos, facedir2dir(facedir)) + new_pos = vector.add(pos, facedir2dir(facedir)) if tRailsExt[get_node_lvm(new_pos).name] then minecart.delete_waypoint(new_pos) end end -function minecart.is_rail(pos) - return tRails[get_node_lvm(pos).name] ~= nil +function minecart.is_rail(pos, name) + return tRails[name or get_node_lvm(pos).name] ~= nil end -- To register node cart names diff --git a/minecart/recording.lua b/minecart/recording.lua index 326450b..d44fa88 100644 --- a/minecart/recording.lua +++ b/minecart/recording.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- -- for lazy programmers @@ -29,7 +29,7 @@ local function dashboard_destroy(self) end local function dashboard_create(self) - if self.driver then + if self.driver then local player = minetest.get_player_by_name(self.driver) if player then dashboard_destroy(self) @@ -51,13 +51,13 @@ local function dashboard_update(self) local player = minetest.get_player_by_name(self.driver) if player then local time = self.runtime or 0 - local dir = (self.ctrl and self.ctrl.left and S("left")) or + local dir = (self.ctrl and self.ctrl.left and S("left")) or (self.ctrl and self.ctrl.right and S("right")) or S("straight") local speed = math.floor((self.curr_speed or 0) + 0.5) - local s = string.format(S("Recording") .. - " | " .. S("speed") .. - ": %.1f | " .. S("next junction") .. - ": %-8s | " .. S("Travel time") .. ": %.1f s", + local s = string.format(S("Recording") .. + " | " .. S("speed") .. + ": %.1f | " .. S("next junction") .. + ": %-8s | " .. S("Travel time") .. ": %.1f s", speed, dir, time) player:hud_change(self.hud_id, "text", s) end @@ -83,7 +83,7 @@ end -- -- Route recording -- -function minecart.start_recording(self, pos) +function minecart.start_recording(self, pos) --print("start_recording") if self.driver then self.start_pos = minecart.get_buffer_pos(pos, self.driver) @@ -103,7 +103,7 @@ function minecart.start_recording(self, pos) end end -function minecart.stop_recording(self, pos, force_exit) +function minecart.stop_recording(self, pos, force_exit) --print("stop_recording") if self.driver and self.is_recording then local dest_pos = minecart.get_buffer_pos(pos, self.driver) @@ -112,7 +112,7 @@ function minecart.stop_recording(self, pos, force_exit) minetest.chat_send_player(self.driver, S("[minecart] Recording canceled!")) elseif dest_pos and player and #self.checkpoints > 3 then -- Remove last checkpoint, because it is potentially too close to the dest_pos - table.remove(self.checkpoints) + table.remove(self.checkpoints) if self.start_pos then local route = { dest_pos = dest_pos, @@ -138,19 +138,19 @@ function minecart.stop_recording(self, pos, force_exit) self.junctions = nil end -function minecart.recording_waypoints(self) +function minecart.recording_waypoints(self) local pos = vector.round(self.object:get_pos()) -- pos correction on slopes if not minecart.is_rail(pos) then pos.y = pos.y - 1 end -- hier müsste überprüfung dest_pos rein - self.sum_speed = self.sum_speed + self.curr_speed + self.sum_speed = self.sum_speed + self.curr_speed local wp_pos = check_waypoint(self, pos) self.checkpoints[#self.checkpoints+1] = { -- cart_pos, next_waypoint_pos, speed, dot - P2H(pos), - P2H(wp_pos), + P2H(pos), + P2H(wp_pos), math.floor(self.curr_speed + 0.5), self.waypoint.dot } diff --git a/minecart/signs.lua b/minecart/signs.lua index 266e161..0bf5c89 100644 --- a/minecart/signs.lua +++ b/minecart/signs.lua @@ -34,10 +34,10 @@ local function register_sign(def) "default_steel_block.png", "default_steel_block.png^"..def.image, }, - + after_place_node = minecart.delete_signs_waypoint, preserve_metadata = minecart.delete_signs_waypoint, - + on_rotate = screwdriver.disallow, paramtype = "light", use_texture_alpha = minecart.CLIP, diff --git a/minecart/storage.lua b/minecart/storage.lua index 1ac383f..66b2ba6 100644 --- a/minecart/storage.lua +++ b/minecart/storage.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- -- for lazy programmers diff --git a/minecart/terminal.lua b/minecart/terminal.lua index 64e4b71..50ad181 100644 --- a/minecart/terminal.lua +++ b/minecart/terminal.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- -- for lazy programmers @@ -25,7 +25,7 @@ end local function formspec(pos, text) text = minetest.formspec_escape(text) text = text:gsub("\n", ",") - + return "size[11,9]".. default.gui_bg.. default.gui_bg_img.. @@ -54,7 +54,7 @@ minetest.register_node("minecart:terminal", { { -8/16, -8/16, 0/16, 8/16, 8/16, 8/16}, }, }, - + after_place_node = function(pos, placer) local meta = M(pos) meta:set_string("owner", placer:get_player_name()) @@ -66,7 +66,7 @@ minetest.register_node("minecart:terminal", { end minetest.get_node_timer(pos):start(2) end, - + on_timer = function(pos, elapsed) if is_player_nearby(pos) then local text = minecart.get_cart_list(pos, M(pos):get_string("owner")) @@ -74,7 +74,7 @@ minetest.register_node("minecart:terminal", { end return true end, - + paramtype2 = "facedir", paramtype = "light", use_texture_alpha = minecart.CLIP, @@ -131,4 +131,4 @@ minetest.register_on_mods_loaded(function() end, }) end -end) \ No newline at end of file +end) diff --git a/minecart/tool.lua b/minecart/tool.lua index 55868a7..3a5ed24 100644 --- a/minecart/tool.lua +++ b/minecart/tool.lua @@ -7,7 +7,7 @@ MIT See license.txt for more information - + ]]-- -- for lazy programmers @@ -19,7 +19,7 @@ local P2H = minetest.hash_node_position local sDir = {[0] = "north", "east", "south", "west"} -local function DOTS(dots) +local function DOTS(dots) if dots then return table.concat(dots, ", ") else @@ -50,15 +50,15 @@ local function test_get_route(pos, node, player) if route.cart_pos then minecart.set_marker(route.cart_pos, "cart", 0.3, 10) end - + -- determine some kind of current y old_pos = old_pos or pos local curr_y = pos.y > old_pos.y and 1 or pos.y < old_pos.y and -1 or 0 - + local cart_pos, extra_cycle = minecart.get_current_cart_pos_correction(pos, facedir, curr_y, route.dot) minecart.set_marker(cart_pos, "curr", 0.3, 10) old_pos = pos - print(string.format("Route: dist = %u, dot = %u, speed = %d, extra cycle = %s", + print(string.format("Route: dist = %u, dot = %u, speed = %d, extra cycle = %s", vector.distance(pos, route.pos), route.dot, route.speed or 0, extra_cycle)) end end diff --git a/networks/README.md b/networks/README.md index 5a197dd..bb1d495 100644 --- a/networks/README.md +++ b/networks/README.md @@ -80,7 +80,7 @@ All this testing nodes can be enabled via mod settings `networks_test_enabled = ### License -Copyright (C) 2021-2022 Joachim Stolberg +Copyright (C) 2021-2023 Joachim Stolberg Code: Licensed under the GNU AGPL version 3 or later. See LICENSE.txt Textures: CC BY-SA 3.0 @@ -131,3 +131,6 @@ Required: tubelib2 **2022-09-10 V0.12** - New API function `networks.liquid.get_liquids` added + +**2023-02-19 V0.13** +- New API function `networks.power.get_storage_percent` added diff --git a/networks/init.lua b/networks/init.lua index 8810e7b..b1f949e 100644 --- a/networks/init.lua +++ b/networks/init.lua @@ -3,7 +3,7 @@ Networks ======== - Copyright (C) 2021 Joachim Stolberg + Copyright (C) 2021-2023 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -13,7 +13,7 @@ networks = {} -- Version for compatibility checks, see readme.md/history -networks.version = 0.12 +networks.version = 0.13 if not minetest.global_exists("tubelib2") or tubelib2.version < 2.2 then minetest.log("error", "[networks] Networks requires tubelib2 version 2.2 or newer!") diff --git a/networks/liquid.lua b/networks/liquid.lua index 3b1b262..476b784 100644 --- a/networks/liquid.lua +++ b/networks/liquid.lua @@ -190,8 +190,9 @@ function networks.liquid.srv_put(nvm, name, amount, capa) assert(capa and capa > 0) amount = math.floor((amount or 0) + 0.5) nvm.liquid = nvm.liquid or {} + nvm.liquid.amount = nvm.liquid.amount or 0 - if not nvm.liquid.name then + if nvm.liquid.amount == 0 or not nvm.liquid.name then nvm.liquid.name = name nvm.liquid.amount = amount return 0 @@ -292,4 +293,4 @@ function networks.liquid.get_liquids(pos, tlib2) out[#out + 1] = k end return out -end \ No newline at end of file +end diff --git a/networks/power.lua b/networks/power.lua index c817c76..712d020 100644 --- a/networks/power.lua +++ b/networks/power.lua @@ -3,7 +3,7 @@ Networks ======== - Copyright (C) 2021 Joachim Stolberg + Copyright (C) 2021-2023 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -439,3 +439,13 @@ function networks.power.get_network_data(pos, tlib2, outdir) end return DEFAULT_DATA end + +function networks.power.get_storage_percent(pos, tlib2, outdir) + assert(outdir) + local netID = networks.determine_netID(pos, tlib2, outdir) + if netID then + local pwr = Power[netID] or get_power_data(pos, tlib2, outdir, netID) + return (pwr.curr_load or 0) * 100 / (pwr.max_capa or 1) + end + return 0 +end diff --git a/signs_bot/README.md b/signs_bot/README.md index 18b2082..650d9a2 100644 --- a/signs_bot/README.md +++ b/signs_bot/README.md @@ -85,6 +85,7 @@ For all Inventory commands applies: If the bot inventory stack specified by ` - dig block under the robot dig_above - dig block above the robot rotate_item - rotate a block in front of the robot + set_param2 - set param2 of the block in front of the robot place_sign - set sign place_sign_behind - put a sign behind the bot dig_sign - remove the sign diff --git a/signs_bot/cmd_place.lua b/signs_bot/cmd_place.lua index 5492755..d78460a 100644 --- a/signs_bot/cmd_place.lua +++ b/signs_bot/cmd_place.lua @@ -395,6 +395,42 @@ signs_bot.register_botcommand("rotate_item", { end, }) +local function set_param2(base_pos, robot_pos, bot_param2, route, level, block_param2) + local pos1 = lib.dest_pos(robot_pos, bot_param2, route) + pos1.y = pos1.y + level + local node = tubelib2.get_node_lvm(pos1) + if not lib.not_protected(base_pos, pos1) then + return signs_bot.ERROR, S("Error: Position protected") + end + if lib.is_simple_node(node) then + if block_param2 then + minetest.swap_node(pos1, {name=node.name, param2=block_param2}) + end + end + return signs_bot.DONE +end + +signs_bot.register_botcommand("set_param2", { + mod = "place", + params = " ", + num_param = 2, + description = S("Set param2 of the block in front of the robot\n".. + " is one of: -1 0 +1\n".. + " is: 0 - 23"), + check = function(lvl, param2) + param2 = tonumber(param2) or 0 + if not param2 or param2 < 0 or param2 > 23 then + return false + end + return tValidLevels[lvl] ~= nil + end, + cmnd = function(base_pos, mem, lvl, param2) + local level = tValidLevels[lvl] + param2 = tonumber(param2) or 0 + return set_param2(base_pos, mem.robot_pos, mem.robot_param2, {0}, level, param2) + end, +}) + -- Simplified torch which can be placed w/o a fake player minetest.register_node("signs_bot:torch", { description = S("Bot torch"), diff --git a/techage/README.md b/techage/README.md index fc4d2ef..7c8ebfd 100644 --- a/techage/README.md +++ b/techage/README.md @@ -27,7 +27,7 @@ In the worst case, the server crashes.** ### License -Copyright (C) 2019-2022 Joachim Stolberg +Copyright (C) 2019-2023 Joachim Stolberg Code: Licensed under the GNU AGPL version 3 or later. See LICENSE.txt Textures: CC BY-SA 3.0 @@ -89,6 +89,24 @@ Available worlds will be converted to 'lsqlite3', but there is no way back, so: ### History +**2023-03-05 V1.11** +- Reduce the number of necessary exp points for TA5 Hyperloop Chest, + TA5 Hyperloop Tank, and TA5 AI Chip II +- Fix possible kernel crashes with TA5 Hyperloop Chest and autocrafter +- Rework doorcontroller (menu changed) +- Increase tank cart storage size to 200 units +- Fix several paramtype/use_texture_alpha issues +- Add command 'load' to the TA4 power terminal +- Add beduino tank commands +- Fix power consumption bug for a stopped collider +- Fix electrolyzer formspec bug +- Add Rack and pinion node +- Expand ta4 sequencer wrench menu +- Accept mincart carts for the move controller +- movecontroller: Allow to move objects 'without' a move block +- Add empty_spool as fab output +- Fix doser goes blocked bug + **2023-02-04 V1.10** - Improve flycontroller - Remove handover for movecontroller diff --git a/techage/basic_machines/autocrafter.lua b/techage/basic_machines/autocrafter.lua index 4212bc2..8402c4e 100644 --- a/techage/basic_machines/autocrafter.lua +++ b/techage/basic_machines/autocrafter.lua @@ -266,6 +266,9 @@ end local function allow_metadata_inventory_put(pos, listname, index, stack, player) + if listname == "output" then + return 0 + end if minetest.is_protected(pos, player:get_player_name()) then return 0 end @@ -285,6 +288,9 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) end local function allow_metadata_inventory_take(pos, listname, index, stack, player) + if listname == "output" then + return 0 + end if minetest.is_protected(pos, player:get_player_name()) then return 0 end @@ -302,6 +308,9 @@ local function allow_metadata_inventory_take(pos, listname, index, stack, player end local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + if from_list == "output" or "to_list" == "output" then + return 0 + end if minetest.is_protected(pos, player:get_player_name()) then return 0 end diff --git a/techage/basic_machines/electronic_fab.lua b/techage/basic_machines/electronic_fab.lua index e6a2640..1ef1934 100644 --- a/techage/basic_machines/electronic_fab.lua +++ b/techage/basic_machines/electronic_fab.lua @@ -77,8 +77,9 @@ local function making(pos, crd, nvm, inv) local owner = M(pos):get_string("owner") local rtype = RecipeType[crd.stage] local recipe = recipes.get(nvm, rtype, owner) - local output = ItemStack(recipe.output.name.." "..recipe.output.num) - if inv:room_for_item("dst", output) then + local output = ItemStack(recipe.output.name .. " " .. recipe.output.num) + local waste = recipe.waste and ItemStack(recipe.waste.name .. " " .. recipe.waste.num) + if inv:room_for_item("dst", output) and (not waste or inv:room_for_item("dst", waste)) then for _,item in ipairs(recipe.input) do local input = ItemStack(item.name.." "..item.num) if not inv:contains_item("src", input) then @@ -91,6 +92,9 @@ local function making(pos, crd, nvm, inv) inv:remove_item("src", input) end inv:add_item("dst", output) + if waste then + inv:add_item("dst", waste) + end crd.State:keep_running(pos, nvm, COUNTDOWN_TICKS) return end diff --git a/techage/basic_machines/ta4_chest.lua b/techage/basic_machines/ta4_chest.lua index b3011c9..89f6e22 100644 --- a/techage/basic_machines/ta4_chest.lua +++ b/techage/basic_machines/ta4_chest.lua @@ -3,7 +3,7 @@ TechAge ======= - Copyright (C) 2019-2022 Joachim Stolberg + Copyright (C) 2019-2023 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -22,6 +22,7 @@ local STACK_SIZE = 2000 local function gen_stack(inv, idx) inv[idx] = {name = "", count = 0} + return inv[idx] end local function gen_inv(nvm) @@ -377,7 +378,7 @@ local function search_chest_in_front(pos, node) pos1 = tubelib2.get_pos(pos1, dir) cnt = cnt + 1 end - if node.name == "techage:ta4_chest" then + if node.name == "techage:ta4_chest" and node.param2 == param2 then minetest.after(1, count_number_of_chests, pos1) local nvm = techage.get_nvm(pos) nvm.front_chest_pos = pos1 diff --git a/techage/basic_machines/ta5_chest.lua b/techage/basic_machines/ta5_chest.lua index d99b051..03a3e45 100644 --- a/techage/basic_machines/ta5_chest.lua +++ b/techage/basic_machines/ta5_chest.lua @@ -3,7 +3,7 @@ TechAge ======= - Copyright (C) 2019-2022 Joachim Stolberg + Copyright (C) 2019-2023 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -19,7 +19,7 @@ local M = minetest.get_meta local S = techage.S local TA4_INV_SIZE = 32 -local EX_POINTS = 20 +local EX_POINTS = 15 local hyperloop = techage.hyperloop local remote_pos = techage.hyperloop.remote_pos @@ -49,7 +49,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) end shared_inv.before_inv_access(pos, listname) local inv = minetest.get_inventory({type="node", pos=pos}) - if inv:room_for_item(listname, stack) then + if inv and inv:room_for_item(listname, stack) then return stack:get_count() end return 0 @@ -61,7 +61,7 @@ local function allow_metadata_inventory_take(pos, listname, index, stack, player end shared_inv.before_inv_access(pos, listname) local inv = minetest.get_inventory({type="node", pos=pos}) - if inv:contains_item(listname, stack) then + if inv and inv:contains_item(listname, stack) then return stack:get_count() end return 0 @@ -141,36 +141,64 @@ minetest.register_node("techage:ta5_hl_chest", { techage.register_node({"techage:ta5_hl_chest"}, { on_inv_request = function(pos, in_dir, access_type) pos = remote_pos(pos) - local meta = minetest.get_meta(pos) - return meta:get_inventory(), "main" + if pos then + local meta = minetest.get_meta(pos) + if meta then + return meta:get_inventory(), "main" + end + end end, on_pull_item = function(pos, in_dir, num, item_name) pos = remote_pos(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return techage.get_items(pos, inv, "main", num) + if pos then + local meta = minetest.get_meta(pos) + if meta then + local inv = meta:get_inventory() + if inv then + return techage.get_items(pos, inv, "main", num) + end + end + end + return false end, on_push_item = function(pos, in_dir, stack) if techage.hyperloop.is_paired(pos) then pos = remote_pos(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return techage.put_items(inv, "main", stack) + if pos then + local meta = minetest.get_meta(pos) + if meta then + local inv = meta:get_inventory() + if inv then + return techage.put_items(inv, "main", stack) + end + end + end end return false end, on_unpull_item = function(pos, in_dir, stack) pos = remote_pos(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return techage.put_items(inv, "main", stack) + if pos then + local meta = minetest.get_meta(pos) + if meta then + local inv = meta:get_inventory() + if inv then + return techage.put_items(inv, "main", stack) + end + end + end + return false end, on_recv_message = function(pos, src, topic, payload) if topic == "state" then - pos = remote_pos(pos) local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return techage.get_inv_state(inv, "main") + if meta then + local inv = meta:get_inventory() + if inv then + return techage.get_inv_state(inv, "main") + end + end + return "error" else return "unsupported" end @@ -178,8 +206,12 @@ techage.register_node({"techage:ta5_hl_chest"}, { on_beduino_request_data = function(pos, src, topic, payload) if topic == 131 then -- Chest State local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return 0, {techage.get_inv_state_num(inv, "main")} + if meta then + local inv = meta:get_inventory() + if inv then + return 0, {techage.get_inv_state_num(inv, "main")} + end + end else return 2, "" end diff --git a/techage/basis/fly_lib.lua b/techage/basis/fly_lib.lua index 6cfcf28..39ac390 100644 --- a/techage/basis/fly_lib.lua +++ b/techage/basis/fly_lib.lua @@ -37,7 +37,8 @@ local function rotate(v, yaw) return {x = v.x * cosyaw - v.z * sinyaw, y = v.y, z = v.x * sinyaw + v.z * cosyaw} end -local function set_node(item) +-- playername is needed for carts, to attach the player to the cart entity +local function set_node(item, playername) local dest_pos = item.dest_pos local name = item.name or "air" local param2 = item.param2 or 0 @@ -49,12 +50,18 @@ local function set_node(item) nvm.running = false M(item.base_pos):set_string("status", S("Stopped")) if ndef1 and ndef2 then - if ndef2.buildable_to then + if minecart.is_cart(name) and (minecart.is_rail(dest_pos, node.name) or minecart.is_cart(name)) then + local player = playername and minetest.get_player_by_name(playername) + minecart.place_and_start_cart(dest_pos, {name = name, param2 = param2}, item.cartdef, player) + return + elseif ndef2.buildable_to then local meta = M(dest_pos) - minetest.set_node(dest_pos, {name=name, param2=param2}) - meta:from_table(item.metadata or {}) - meta:set_string("ta_move_block", "") - meta:set_int("ta_door_locked", 1) + if name ~= "techage:moveblock" then + minetest.set_node(dest_pos, {name=name, param2=param2}) + meta:from_table(item.metadata or {}) + meta:set_string("ta_move_block", "") + meta:set_int("ta_door_locked", 1) + end return end local meta = M(dest_pos) @@ -63,7 +70,9 @@ local function set_node(item) return end elseif ndef1 then - minetest.add_item(dest_pos, ItemStack(name)) + if name ~= "techage:moveblock" then + minetest.add_item(dest_pos, ItemStack(name)) + end end end @@ -294,7 +303,7 @@ local function detach_player(player) end -- Attach player/mob to given parent object (block) -local function attach_single_object(parent, obj, dir) +local function attach_single_object(parent, obj, distance) local self = parent:get_luaentity() local res = obj:get_attach() if not res then -- not already attached @@ -305,20 +314,20 @@ local function attach_single_object(parent, obj, dir) yaw = obj:get_rotation().y end -- store for later use - local offs = table.copy(dir) + local offs = table.copy(distance) -- Calc entity rotation, which is relative to the parent's rotation local rot = parent:get_rotation() if self.param2 >= 20 then - dir = rotate(dir, 2 * math.pi - rot.y) - dir.y = -dir.y - dir.x = -dir.x + distance = rotate(distance, 2 * math.pi - rot.y) + distance.y = -distance.y + distance.x = -distance.x rot.y = rot.y - yaw elseif self.param2 < 4 then - dir = rotate(dir, 2 * math.pi - rot.y) + distance = rotate(distance, 2 * math.pi - rot.y) rot.y = rot.y - yaw end - dir = vector.multiply(dir, 29) - obj:set_attach(parent, "", dir, vector.multiply(rot, 180 / math.pi)) + distance = vector.multiply(distance, 29) + obj:set_attach(parent, "", distance, vector.multiply(rot, 180 / math.pi)) obj:set_properties({visual_size = {x=2.9, y=2.9}}) if obj:is_player() then if lock_player(obj) then @@ -332,19 +341,21 @@ end -- Attach all objects around to the parent object -- offs is the search/attach position offset -local function attach_objects(pos, offs, parent, yoffs) +-- distance (optional) is the attach distance to the center of the entity +local function attach_objects(pos, offs, parent, yoffs, distance) local pos1 = vector.add(pos, offs) for _, obj in pairs(minetest.get_objects_inside_radius(pos1, 0.9)) do - local dir = vector.subtract(obj:get_pos(), pos) + -- keep relative object position + distance = distance or vector.subtract(obj:get_pos(), pos) local entity = obj:get_luaentity() if entity then local mod = entity.name:gmatch("(.-):")() if techage.RegisteredMobsMods[mod] then - dir.y = dir.y + yoffs - attach_single_object(parent, obj, dir) + distance.y = distance.y + yoffs + attach_single_object(parent, obj, distance) end elseif obj:is_player() then - attach_single_object(parent, obj, dir) + attach_single_object(parent, obj, distance) end end end @@ -380,10 +391,11 @@ end local function entity_to_node(pos, obj) local self = obj:get_luaentity() if self and self.item then + local playername = self.players and self.players[1] and self.players[1].name detach_objects(pos, self) monitoring_del_entity(self.item) minetest.after(0.1, obj.remove, obj) - set_node(self.item) + set_node(self.item, playername) end end @@ -392,9 +404,12 @@ end -- * start_pos and dest_pos are entity positions local function node_to_entity(base_pos, start_pos, dest_pos) local meta = M(start_pos) - local node, metadata + local node, metadata, cartdef - if meta:contains("ta_move_block") then + node = techage.get_node_lvm(start_pos) + if minecart.is_cart(node.name) then + cartdef = minecart.remove_cart(start_pos) + elseif meta:contains("ta_move_block") then -- Move-block stored as metadata node = minetest.deserialize(meta:get_string("ta_move_block")) metadata = {} @@ -424,6 +439,7 @@ local function node_to_entity(base_pos, start_pos, dest_pos) metadata = metadata or {}, dest_pos = dest_pos, base_pos = base_pos, + cartdef = cartdef, } monitoring_add_entity(self.item) @@ -432,7 +448,7 @@ local function node_to_entity(base_pos, start_pos, dest_pos) self.entities = {} -- Prepare for path walk self.path_idx = 1 - return obj + return obj, self.item.cartdef ~= nil end end @@ -536,6 +552,9 @@ local function is_valid_dest(pos) if techage.is_air_like(node.name) then return true end + if minecart.is_rail(pos, node.name) or minecart.is_cart(node.name) then + return true + end if not M(pos):contains("ta_move_block") then return true end @@ -543,9 +562,15 @@ local function is_valid_dest(pos) end local function is_simple_node(pos) - local node =techage.get_node_lvm(pos) - local ndef = minetest.registered_nodes[node.name] - return not techage.is_air_like(node.name) and techage.can_dig_node(node.name, ndef) + local node = techage.get_node_lvm(pos) + if not minecart.is_rail(pos, node.name) then + if node.name == "air" then + minetest.swap_node(pos, {name = "techage:moveblock", param2 = 0}) + return true + end + local ndef = minetest.registered_nodes[node.name] + return not techage.is_air_like(node.name) and techage.can_dig_node(node.name, ndef) or minecart.is_cart(node.name) + end end -- Move node from 'pos1' to the destination, calculated by means of 'lmove' @@ -562,14 +587,18 @@ local function move_node(pos, meta, pos1, lmove, max_speed, height) if pos2 then local dir = determine_dir(pos1, pos2) - local obj = node_to_entity(pos, pos1, dest_pos) + local obj, is_cart = node_to_entity(pos, pos1, dest_pos) if obj then - local offs = {x=0, y=height or 1, z=0} - attach_objects(pos1, offs, obj, yoffs) - if dir.y == 0 then - if (dir.x ~= 0 and dir.z == 0) or (dir.x == 0 and dir.z ~= 0) then - attach_objects(pos1, dir, obj, yoffs) + if is_cart then + attach_objects(pos1, 0, obj, yoffs, {x = 0, y = -0.4, z = 0}) + else + local offs = {x=0, y=height or 1, z=0} + attach_objects(pos1, offs, obj, yoffs) + if dir.y == 0 then + if (dir.x ~= 0 and dir.z == 0) or (dir.x == 0 and dir.z ~= 0) then + attach_objects(pos1, dir, obj, yoffs) + end end end local self = obj:get_luaentity() @@ -801,6 +830,21 @@ function flylib.remove_node(pos) end end +minetest.register_node("techage:moveblock", { + description = "Techage Move Block", + drawtype = "normal", + tiles = {"techage_invisible.png"}, + sunlight_propagates = true, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + floodable = true, + is_ground_content = false, + groups = {not_in_creative_inventory=1}, + drop = "", +}) + minetest.register_on_joinplayer(function(player) unlock_player(player) end) diff --git a/techage/basis/hyperloop.lua b/techage/basis/hyperloop.lua index e89b972..32e7b0a 100644 --- a/techage/basis/hyperloop.lua +++ b/techage/basis/hyperloop.lua @@ -184,7 +184,7 @@ function techage.hyperloop.remote_pos(pos) local nvm = techage.get_nvm(pos) if Stations:get(nvm.rmt_pos) then if M(pos):contains("remote_name") then - return nvm.rmt_pos + return nvm.rmt_pos or pos end end end diff --git a/techage/basis/liquid_lib.lua b/techage/basis/liquid_lib.lua index 34a7e37..1075e1a 100644 --- a/techage/basis/liquid_lib.lua +++ b/techage/basis/liquid_lib.lua @@ -75,6 +75,24 @@ techage.liquid.recv_message = { return "unsupported" end end, + on_beduino_request_data = function(pos, src, topic, payload) + local nvm = techage.get_nvm(pos) + if topic == 128 then + return 0, techage.get_node_lvm(pos).name + elseif topic == 134 then + local nvm = techage.get_nvm(pos) + nvm.liquid = nvm.liquid or {} + nvm.liquid.amount = nvm.liquid.amount or 0 + if payload[1] == 1 then + local value = techage.power.percent(LQD(pos).capa, nvm.liquid.amount) + return 0, {math.floor(value + 0.5)} + else + return 0, {nvm.liquid.amount} + end + else + return 2, "" + end + end, } -- like: register_liquid("techage:ta3_barrel_oil", "techage:ta3_barrel_empty", 10, "techage:oil") diff --git a/techage/basis/recipe_lib.lua b/techage/basis/recipe_lib.lua index e583c71..fc069b6 100644 --- a/techage/basis/recipe_lib.lua +++ b/techage/basis/recipe_lib.lua @@ -159,8 +159,10 @@ function techage.recipes.on_receive_fields(pos, formname, fields, player) if not nvm.running then if fields.next == ">>" then nvm.recipe_idx = nvm.recipe_idx + 1 + return true elseif fields.priv == "<<" then nvm.recipe_idx = nvm.recipe_idx - 1 + return true end end end diff --git a/techage/basis/shared_inv.lua b/techage/basis/shared_inv.lua index 4169d3e..2c5138b 100644 --- a/techage/basis/shared_inv.lua +++ b/techage/basis/shared_inv.lua @@ -3,7 +3,7 @@ TechAge ======= - Copyright (C) 2019-2022 Joachim Stolberg + Copyright (C) 2019-2023 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -31,7 +31,7 @@ end function techage.shared_inv.node_timer(pos, elapsed) local rmt_pos = remote_pos(pos) - if techage.is_activeformspec(pos) then + if rmt_pos and techage.is_activeformspec(pos) then copy_inventory_list(rmt_pos, pos, "main") return true end @@ -42,8 +42,10 @@ end function techage.shared_inv.before_inv_access(pos, listname) if hyperloop.is_client(pos) then local rmt_pos = remote_pos(pos) - copy_inventory_list(rmt_pos, pos, listname) - return true + if rmt_pos then + copy_inventory_list(rmt_pos, pos, listname) + return true + end end return false end @@ -52,8 +54,10 @@ end function techage.shared_inv.after_inv_access(pos, listname) if hyperloop.is_client(pos) then local rmt_pos = remote_pos(pos) - copy_inventory_list(pos, rmt_pos, listname) - return true + if rmt_pos then + copy_inventory_list(pos, rmt_pos, listname) + return true + end end return false end @@ -61,8 +65,10 @@ end function techage.shared_inv.on_rightclick(pos, clicker, listname) if hyperloop.is_client(pos) then local rmt_pos = remote_pos(pos) - copy_inventory_list(rmt_pos, pos, listname) - techage.set_activeformspec(pos, clicker) - minetest.get_node_timer(pos):start(2) + if rmt_pos then + copy_inventory_list(rmt_pos, pos, listname) + techage.set_activeformspec(pos, clicker) + minetest.get_node_timer(pos):start(2) + end end end diff --git a/techage/carts/tank_cart.lua b/techage/carts/tank_cart.lua index cbb1db1..48796b4 100644 --- a/techage/carts/tank_cart.lua +++ b/techage/carts/tank_cart.lua @@ -21,7 +21,7 @@ local Pipe = techage.LiquidPipe local MP = minetest.get_modpath("minecart") local liquid = networks.liquid -local CAPACITY = 100 +local CAPACITY = 200 local function on_rightclick(pos, node, clicker) if clicker and clicker:is_player() then diff --git a/techage/chemistry/ta4_doser.lua b/techage/chemistry/ta4_doser.lua index ca99fb9..8cb9009 100644 --- a/techage/chemistry/ta4_doser.lua +++ b/techage/chemistry/ta4_doser.lua @@ -272,7 +272,11 @@ local function on_receive_fields(pos, formname, fields, player) local nvm = techage.get_nvm(pos) if not nvm.running then - recipes.on_receive_fields(pos, formname, fields, player) + if recipes.on_receive_fields(pos, formname, fields, player) then + local mem = techage.get_mem(pos) + mem.waste_leftover = nil + mem.output_leftover = nil + end end local mem = techage.get_mem(pos) mem.dbg_cycles = 5 diff --git a/techage/coal_power_station/turbine.lua b/techage/coal_power_station/turbine.lua index 5d825e4..a516a95 100644 --- a/techage/coal_power_station/turbine.lua +++ b/techage/coal_power_station/turbine.lua @@ -82,7 +82,7 @@ minetest.register_node("techage:turbine", { "techage_filling_ta3.png^techage_frame_ta3.png", "techage_filling_ta3.png^techage_appl_open.png^techage_frame_ta3.png", "techage_filling_ta3.png^techage_frame_ta3.png^techage_steam_hole.png", - "techage_filling_ta3.png^techage_appl_turbine.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_appl_turbine.png^techage_frame_ta3.png^[transformFX", "techage_filling_ta3.png^techage_appl_turbine.png^techage_frame_ta3.png", }, @@ -105,7 +105,7 @@ minetest.register_node("techage:turbine_on", { "techage_filling_ta3.png^techage_appl_open.png^techage_frame_ta3.png", "techage_filling_ta3.png^techage_frame_ta3.png^techage_steam_hole.png", { - image = "techage_filling4_ta3.png^techage_appl_turbine4.png^techage_frame4_ta3.png", + image = "techage_filling4_ta3.png^techage_appl_turbine4.png^techage_frame4_ta3.png^[transformFX", backface_culling = false, animation = { type = "vertical_frames", diff --git a/techage/collider/detector.lua b/techage/collider/detector.lua index 494d6b9..c5dee94 100644 --- a/techage/collider/detector.lua +++ b/techage/collider/detector.lua @@ -3,7 +3,7 @@ TechAge ======= - Copyright (C) 2019-2021 Joachim Stolberg + Copyright (C) 2019-2023 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -157,7 +157,7 @@ local function create_task(pos, task) end -- Call on_cyclic_check of all magents so that the magnets don't need a FLB. -local function magnet_on_cyclic_check(pos, nvm) +local function magnets_on_cyclic_check(pos, nvm) local ndef = minetest.registered_nodes["techage:ta4_magnet"] for idx,pos2 in ipairs(nvm.magnet_positions or {}) do local res = ndef.on_cyclic_check(pos2) @@ -173,6 +173,29 @@ local function magnet_on_cyclic_check(pos, nvm) return true end +-- Turn off all magnets so that they don't consume power +local function magnets_turn_off(pos, nvm) + local ndef = minetest.registered_nodes["techage:ta4_magnet"] + for idx,pos2 in ipairs(nvm.magnet_positions or {}) do + ndef.on_turn_off(pos2) + end +end + +local function cable_inlets_turn_on_off(pos, on) + local turn_on_off = function(pos, param2, item) + local pos2 = getpos(pos, param2, item.route, item.yoffs) + local node2 = minetest.get_node(pos2) + if item.name == node2.name then + local nvm = techage.get_nvm(pos2) + techage.power_inlet_turn_on_off(pos2, nvm, on) + end + end + + local param2 = minetest.get_node(pos).param2 + turn_on_off(pos, param2, Schedule[2]) + turn_on_off(pos, param2, Schedule[3]) +end + minetest.register_node("techage:ta4_detector_core", { description = S("TA4 Collider Detector Core"), tiles = { @@ -202,29 +225,33 @@ minetest.register_node("techage:ta4_detector_core", { on_timer = function(pos, elapsed) local nvm = techage.get_nvm(pos) - if not magnet_on_cyclic_check(pos, nvm) then - techage.del_laser(pos) - if nvm.running then - terminal_message(pos, "Detector stopped.") - nvm.running = false - end - nvm.magnet_positions = nil - elseif nvm.running then - local res = check_state(pos) - if res == true then - experience_points(pos) - add_laser(pos) - if nvm.ticks <= TIME_SLOTS then -- only once - terminal_message(pos, "Detector running.") - end - elseif res == false then + if nvm.running then + if not magnets_on_cyclic_check(pos, nvm) then techage.del_laser(pos) + terminal_message(pos, "Detector stopped.") + magnets_turn_off(pos, nvm) + cable_inlets_turn_on_off(pos, false) nvm.running = false nvm.magnet_positions = nil - terminal_message(pos, "Detector stopped.") - end - if nvm.running then - play_sound(pos) + else + local res = check_state(pos) + if res == true then + experience_points(pos) + add_laser(pos) + if nvm.ticks <= TIME_SLOTS then -- only once + terminal_message(pos, "Detector running.") + end + elseif res == false then + techage.del_laser(pos) + magnets_turn_off(pos, nvm) + cable_inlets_turn_on_off(pos, false) + nvm.running = false + nvm.magnet_positions = nil + terminal_message(pos, "Detector stopped.") + end + if nvm.running then + play_sound(pos) + end end end return true @@ -287,6 +314,7 @@ local function start_task(pos) end nvm.magnet_positions = t techage.send_single(own_num, term_num, "append", "ok") + cable_inlets_turn_on_off(pos, true) coroutine.yield() techage.send_single(own_num, term_num, "text", "- Check magnets...") @@ -310,6 +338,7 @@ local function start_task(pos) techage.send_single(own_num, term_num, "append", err .. "!!!") nvm.magnet_positions = nil nvm.locked = false + cable_inlets_turn_on_off(pos, false) return end else @@ -323,12 +352,14 @@ local function start_task(pos) techage.send_single(own_num, term_num, "append", err .. "!!!") nvm.magnet_positions = nil nvm.locked = false + cable_inlets_turn_on_off(pos, false) return end else techage.send_single(own_num, term_num, "append", "defect!!!") nvm.magnet_positions = nil nvm.locked = false + cable_inlets_turn_on_off(pos, false) return end coroutine.yield() @@ -337,7 +368,7 @@ local function start_task(pos) techage.send_single(own_num, term_num, "append", "ok") coroutine.yield() - techage.send_single(own_num, term_num, "text", "Collider started.") + techage.send_single(own_num, term_num, "text", "Collider starting...") nvm.ticks = 0 nvm.running = true end @@ -372,6 +403,9 @@ techage.register_node({"techage:ta4_detector_core"}, { nvm.running = false techage.del_laser(pos) nvm.locked = false + magnets_turn_off(pos, nvm) + cable_inlets_turn_on_off(pos, false) + nvm.magnet_positions = nil return "Detector stopped." elseif topic == "status" then if nvm.running == true then diff --git a/techage/collider/inlets.lua b/techage/collider/inlets.lua index 7826026..2f60662 100644 --- a/techage/collider/inlets.lua +++ b/techage/collider/inlets.lua @@ -328,7 +328,11 @@ minetest.register_node("techage:ta4_collider_cable_inlet", { on_timer = function(pos, elapsed) local nvm = techage.get_nvm(pos) - nvm.consumed = power.consume_power(pos, Cable, nil, PWR_NEEDED) + if nvm.running then + nvm.consumed = power.consume_power(pos, Cable, nil, PWR_NEEDED) + else + nvm.consumed = 0 + end return true end, @@ -346,6 +350,11 @@ function techage.power_inlet_check(pos, node, meta, nvm) return false, "no power" end +-- Used by the detector to turn on/off the node +function techage.power_inlet_turn_on_off(pos, nvm, on) + nvm.running = on +end + power.register_nodes({"techage:ta4_collider_cable_inlet"}, Cable, "con", {"F"}) techage.register_node({"techage:ta4_collider_cable_inlet"}, { diff --git a/techage/collider/magnet.lua b/techage/collider/magnet.lua index 4062413..73dc365 100644 --- a/techage/collider/magnet.lua +++ b/techage/collider/magnet.lua @@ -3,7 +3,7 @@ TechAge ======= - Copyright (C) 2019-2021 Joachim Stolberg + Copyright (C) 2019-2023 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -93,6 +93,8 @@ minetest.register_node("techage:ta4_magnet", { }, wield_scale = {x = 0.8, y = 0.8, z = 0.8}, paramtype2 = "facedir", + paramtype = "light", + use_texture_alpha = techage.CLIP, groups = {cracky = 1}, on_rotate = screwdriver.disallow, is_ground_content = false, @@ -119,14 +121,22 @@ minetest.register_node("techage:ta4_magnet", { nvm.consumed = power.consume_power(pos, Cable, 6, PWR_NEEDED) if nvm.tube_damage then nvm.tube_damage = nil + nvm.running = nil return -1 elseif nvm.liquid.amount == CAPACITY and nvm.liquid.name == "techage:isobutane" and nvm.consumed == PWR_NEEDED then + nvm.running = true return 0 end + nvm.running = nil return -2 end, + + on_turn_off = function(pos) + local nvm = techage.get_nvm(pos) + nvm.running = nil + end, tubelib2_on_update2 = function(pos, outdir, tlib2, node) if tlib2.tube_type == "vtube" then diff --git a/techage/doc/manual_DE.lua b/techage/doc/manual_DE.lua index 99c276f..9e910d8 100644 --- a/techage/doc/manual_DE.lua +++ b/techage/doc/manual_DE.lua @@ -21,7 +21,6 @@ techage.manual_DE.aTitel = { "3,TA1 Schleusengriff / TA1 Sluice Handle", "3,TA1 Apfelholzbrett / TA1 Apple Wood Board", "3,TA1 Apfel Mühlbachbrett / TA1 Apple Millrace Board", - "2, ", "2,Erze und Werkzeuge", "3,Hammer", "3,Kiessieb / Gravel Sieve", @@ -432,7 +431,6 @@ techage.manual_DE.aText = { "\n".. "\n".. "\n", - "", "TA1 hat seine eigenen Werkzeuge wie Hammer und Kiessieb\\, aber auch der Minecart Hopper kann genutzt werden.\n".. "\n".. "\n".. @@ -981,7 +979,7 @@ techage.manual_DE.aText = { "\n", "Der Tankwagen dient zum Transport von Flüssigkeiten. Es kann wie Tanks mit Pumpen gefüllt bzw. geleert werden. In beiden Fällen muss die gelbe Röhre von oben mit dem Tankwagen verbunden werden.\n".. "\n".. - "In den Tankwagen passen 100 Einheiten.\n".. + "In den Tankwagen passen 200 Einheiten.\n".. "\n".. "\n".. "\n", @@ -1726,7 +1724,6 @@ techage.manual_DE.aText = { " - mit den Menü-Tasten \"Bewege A-B\" sowie \"Bewege B-A\" kann die Bewegung getestet werden\n".. " - man kann auch durch Wände oder andere Blöcke fliegen\n".. " - auch die Zielposition für die Blöcke kann belegt sein. Die Blöcke werden in diesem Falle \"unsichtbar\" gespeichert. Dies ist für Schiebetüren und ähnliches gedacht\n".. - " - Über das Gabelschlüssel-Menü kann im Controller auch ein \"handover\" programmiert werden. Durch Eingabe einer Blocknummer werden die Blöcke dann an den nächsten Move Controller übergeben. So lassen sich auch zusammenhängende Bewegungen über mehrere Move Controller realisieren.\n".. "\n".. "Der Move Controller unterstützt folgende techage Kommandos:\n".. "\n".. @@ -2112,7 +2109,7 @@ techage.manual_DE.aText = { "\n".. "Für das Pairing musst du zuerst auf der einen Seite einen Namen für die Kiste eingeben\\, dann kannst du bei der anderen Kiste diesen Namen auswählen und so die beiden Blöcke verbinden.\n".. "\n".. - "Die Nutzung der TA5 Hyperloop Kiste benötigt 20 Erfahrungspunkte.\n".. + "Die Nutzung der TA5 Hyperloop Kiste benötigt 15 Erfahrungspunkte.\n".. "\n".. "\n".. "\n", @@ -2122,7 +2119,7 @@ techage.manual_DE.aText = { "\n".. "Für das Pairing musst du zuerst auf der einen Seite einen Namen für den Tank eingeben\\, dann kannst du bei dem anderen Tank diesen Namen auswählen und so die beiden Blöcke verbinden.\n".. "\n".. - "Die Nutzung des TA5 Hyperloop Tanks benötigt 20 Erfahrungspunkte.\n".. + "Die Nutzung des TA5 Hyperloop Tanks benötigt 15 Erfahrungspunkte.\n".. "\n".. "\n".. "\n", @@ -2134,25 +2131,25 @@ techage.manual_DE.aText = { "\n".. "\n".. "\n", - "Diese Teleport-Blöcke erlauben die Übertragung von Gegenständen und ersetzen somit eine Röhre. Dabei können Entfernungen von bis zu 200 Blöcken überbrückt werden.\n".. + "Diese Teleport-Blöcke erlauben die Übertragung von Gegenständen und ersetzen somit eine Röhre. Dabei können Entfernungen von bis zu 500 Blöcken überbrückt werden.\n".. "\n".. "Ein Teleport-Block benötigt 12 ku Strom.\n".. "\n".. - "Für die Nutzung der Teleport-Blöcke werden 60 Erfahrungspunkte benötigt.\n".. + "Für die Nutzung der Teleport-Blöcke werden 30 Erfahrungspunkte benötigt.\n".. "\n".. "\n".. "\n", - "Diese Teleport-Blöcke erlauben die Übertragung von Flüssigkeiten und ersetzen somit eine gelbe Leitung. Dabei können Entfernungen von bis zu 200 Blöcken überbrückt werden.\n".. + "Diese Teleport-Blöcke erlauben die Übertragung von Flüssigkeiten und ersetzen somit eine gelbe Leitung. Dabei können Entfernungen von bis zu 500 Blöcken überbrückt werden.\n".. "\n".. "Ein Teleport-Block benötigt 12 ku Strom.\n".. "\n".. - "Für die Nutzung der Teleport-Blöcke werden 60 Erfahrungspunkte benötigt.\n".. + "Für die Nutzung der Teleport-Blöcke werden 30 Erfahrungspunkte benötigt.\n".. "\n".. "\n".. "\n", "Die Hyperloop Teleport Blöcke erlauben den Aufbau von Hyperloop Netzwerk ohne Hyperloop-Röhren.\n".. "\n".. - "Die Nutzung der Hyperloop Teleport Blöcke benötigt 120 Erfahrungspunkte.\n".. + "Die Nutzung der Hyperloop Teleport Blöcke benötigt 60 Erfahrungspunkte.\n".. "\n", "", "Der TA5 Container erlaubt Techage Anlagen ein- und an einer anderen Stelle wieder auszupacken.\n".. @@ -2163,7 +2160,7 @@ techage.manual_DE.aText = { "\n".. "\n".. "\n", - "Der TA5 KI Chip II wird zur Herstellung des TA5 Fusionsreaktors benötigt. Der TA5 KI Chip II kann nur auf der TA4 Elektronik Fab hergestellt werden. Dazu werden 50 Erfahrungspunkte benötigt.\n".. + "Der TA5 KI Chip II wird zur Herstellung des TA5 Fusionsreaktors benötigt. Der TA5 KI Chip II kann nur auf der TA4 Elektronik Fab hergestellt werden. Dazu werden 25 Erfahrungspunkte benötigt.\n".. "\n".. "\n".. "\n", @@ -2190,7 +2187,6 @@ techage.manual_DE.aItemName = { "ta1_sluice_handle", "ta1_board1", "ta1_board2", - "", "ta1_gravelsieve", "hammer", "ta1_gravelsieve", @@ -2451,7 +2447,6 @@ techage.manual_DE.aPlanTable = { "", "", "", - "", "hoppersieve", "", "", diff --git a/techage/doc/manual_EN.lua b/techage/doc/manual_EN.lua index 7766052..0e8365f 100644 --- a/techage/doc/manual_EN.lua +++ b/techage/doc/manual_EN.lua @@ -983,7 +983,7 @@ techage.manual_EN.aText = { "\n", "The tank truck is used to transport liquids. Like tanks\\, it can be filled with pumps or emptied. In both cases\\, the yellow tube must be connected to the tank truck from above.\n".. "\n".. - "100 units fit in the tank truck.\n".. + "200 units fit in the tank truck.\n".. "\n".. "\n".. "\n", @@ -1731,7 +1731,6 @@ techage.manual_EN.aText = { " - The movement can be tested with the menu buttons \"Move A-B\" and \"Move B-A\"\n".. " - you can also fly through walls or other blocks\n".. " - The target position for the blocks can also be occupied. In this case\\, the blocks are saved \"invisibly\". This is intended for sliding doors and the like\n".. - " - A \"handover\" can also be programmed in the controller via the open-ended wrench menu. By entering a block number\\, the blocks are then transferred to the next move controller. In this way\\, connected movements can also be implemented using several Move Controllers.\n".. "\n".. "The Move Controller supports the following techage commands:\n".. "\n".. @@ -2118,7 +2117,7 @@ techage.manual_EN.aText = { "\n".. "For pairing you first have to enter a name for the chest on one side\\, then you can select this name for the other chest and thus connect the two blocks.\n".. "\n".. - "The use of the TA5 Hyperloop Chest requires 20 experience points.\n".. + "The use of the TA5 Hyperloop Chest requires 15 experience points.\n".. "\n".. "\n".. "\n", @@ -2128,7 +2127,7 @@ techage.manual_EN.aText = { "\n".. "For pairing you first have to enter a name for the tank on one side\\, then you can select this name for the other tank and thus connect the two blocks.\n".. "\n".. - "The use of the TA5 Hyperloop Tank requires 20 experience points.\n".. + "The use of the TA5 Hyperloop Tank requires 15 experience points.\n".. "\n".. "\n".. "\n", @@ -2138,25 +2137,25 @@ techage.manual_EN.aText = { "\n".. "\n".. "\n", - "These teleport blocks allow the transfer of items and thus replace a tube. Distances of up to 200 blocks can be bridged.\n".. + "These teleport blocks allow the transfer of items and thus replace a tube. Distances of up to 500 blocks can be bridged.\n".. "\n".. "Each Teleport blocks requires 12 ku of electricity.\n".. "\n".. - "60 experience points are required to use the teleport blocks. \n".. + "30 experience points are required to use the teleport blocks. \n".. "\n".. "\n".. "\n", - "These teleport blocks allow the transfer of liquids and thus replace a pipe. Distances of up to 200 blocks can be bridged.\n".. + "These teleport blocks allow the transfer of liquids and thus replace a pipe. Distances of up to 500 blocks can be bridged.\n".. "\n".. "Each Teleport blocks requires 12 ku of electricity.\n".. "\n".. - "60 experience points are required to use the teleport blocks. \n".. + "30 experience points are required to use the teleport blocks. \n".. "\n".. "\n".. "\n", "The Hyperloop Teleport Blocks allow the construction of a Hyperloop network without Hyperloop tubes.\n".. "\n".. - "The use of the Hyperloop Teleport Blocks requires 120 experience points.\n".. + "The use of the Hyperloop Teleport Blocks requires 60 experience points.\n".. "\n", "", "The TA5 container allows Techage systems to be packed and unpacked at another location.\n".. @@ -2167,7 +2166,7 @@ techage.manual_EN.aText = { "\n".. "\n".. "\n", - "The TA5 AI Chip II is required to build the TA5 Fusion Reactor. The TA5 AI Chip II can only be manufactured at the TA4 Electronics Fab. This requires 50 experience points.\n".. + "The TA5 AI Chip II is required to build the TA5 Fusion Reactor. The TA5 AI Chip II can only be manufactured at the TA4 Electronics Fab. This requires 25 experience points.\n".. "\n".. "\n".. "\n", diff --git a/techage/energy_storage/heatexchanger2.lua b/techage/energy_storage/heatexchanger2.lua index dc4b1d3..938f9f2 100644 --- a/techage/energy_storage/heatexchanger2.lua +++ b/techage/energy_storage/heatexchanger2.lua @@ -347,10 +347,10 @@ techage.register_node({"techage:heatexchanger2"}, { elseif topic == "load" then return techage.power.percent(nvm.capa_max, nvm.capa) elseif topic == "on" then - start_node(pos, techage.get_nvm(pos)) + State:start(pos, nvm) return true elseif topic == "off" then - stop_node(pos, techage.get_nvm(pos)) + State:stop(pos, nvm) return true else return "unsupported" @@ -359,10 +359,10 @@ techage.register_node({"techage:heatexchanger2"}, { on_beduino_receive_cmnd = function(pos, src, topic, payload) local nvm = techage.get_nvm(pos) if topic == 1 and payload[1] == 1 then - start_node(pos, techage.get_nvm(pos)) + State:start(pos, nvm) return 0 elseif topic == 1 and payload[1] == 0 then - stop_node(pos, techage.get_nvm(pos)) + State:stop(pos, nvm) return 0 else return 2, "" @@ -382,7 +382,8 @@ techage.register_node({"techage:heatexchanger2"}, { local data = power.get_network_data(pos, Cable, DOWN) return 0, {data.consumed - data.provided} elseif topic == 134 then -- Tank Load Percent - return 0, {techage.power.percent(nvm.capa_max, nvm.capa)} + local value = techage.power.percent(nvm.capa_max, nvm.capa) + return 0, {math.floor(value + 0.5)} else return 2, "" end diff --git a/techage/hydrogen/electrolyzer.lua b/techage/hydrogen/electrolyzer.lua index 599d489..9cab71f 100644 --- a/techage/hydrogen/electrolyzer.lua +++ b/techage/hydrogen/electrolyzer.lua @@ -26,6 +26,7 @@ local STANDBY_TICKS = 3 local PWR_NEEDED = 35 local PWR_UNITS_PER_HYDROGEN_ITEM = 80 local CAPACITY = 200 +local TURNOFF_THRESHOLD = "40%" local function evaluate_percent(s) return (tonumber(s:sub(1, -2)) or 0) / 100 @@ -124,11 +125,14 @@ local function node_timer(pos, elapsed) State:keep_running(pos, nvm, 1) end elseif curr_load == 0 then + nvm.taken = 0 State:nopower(pos, nvm) else + nvm.taken = 0 State:standby(pos, nvm, S("Turnoff point reached")) end else + nvm.taken = 0 State:blocked(pos, nvm, S("Storage full")) end if techage.is_activeformspec(pos) then @@ -161,6 +165,8 @@ local function after_place_node(pos) State:node_init(pos, nvm, number) local node = minetest.get_node(pos) M(pos):set_int("in_dir", techage.side_to_indir("R", node.param2)) + M(pos):set_string("reduction", "100%") + M(pos):set_string("turnoff", TURNOFF_THRESHOLD) Pipe:after_place_node(pos) Cable:after_place_node(pos) end @@ -201,7 +207,7 @@ local tool_config = { name = "turnoff", label = S("Turnoff point"), tooltip = S("If the charge of the storage\nsystem falls below the configured value,\nthe block switches off"), - default = "98%", + default = TURNOFF_THRESHOLD, }, } @@ -349,7 +355,7 @@ techage.register_node({"techage:ta4_electrolyzer", "techage:ta4_electrolyzer_on" local meta = M(pos) if not meta:contains("reduction") then meta:set_string("reduction", "100%") - meta:set_string("turnoff", "100%") + meta:set_string("turnoff", TURNOFF_THRESHOLD) end end, }) diff --git a/techage/icta_controller/display.lua b/techage/icta_controller/display.lua index 1b1b1bc..62d5215 100644 --- a/techage/icta_controller/display.lua +++ b/techage/icta_controller/display.lua @@ -219,7 +219,7 @@ function techage.display.write_row(pos, payload, cycle_time, beduino) nvm.text = nvm.text or {} mem.ticks = mem.ticks or 0 - if beduino then + if beduino or type(payload) == "string" then row = tonumber(payload:sub(1,1) or "1") or 1 str = payload:sub(2) or "oops" else diff --git a/techage/init.lua b/techage/init.lua index 445c829..fb9cae4 100644 --- a/techage/init.lua +++ b/techage/init.lua @@ -13,7 +13,7 @@ techage = {} -- Version for compatibility checks, see readme.md/history -techage.version = 1.10 +techage.version = 1.11 if minetest.global_exists("tubelib") then minetest.log("error", "[techage] Techage can't be used together with the mod tubelib!") @@ -27,8 +27,8 @@ elseif minetest.global_exists("techpack") then elseif minetest.global_exists("tubelib2") and tubelib2.version < 2.2 then minetest.log("error", "[techage] Techage requires tubelib2 version 2.2 or newer!") return -elseif minetest.global_exists("minecart") and minecart.version < 2.03 then - minetest.log("error", "[techage] Techage requires minecart version 2.03 or newer!") +elseif minetest.global_exists("minecart") and minecart.version < 2.04 then + minetest.log("error", "[techage] Techage requires minecart version 2.04 or newer!") return elseif minetest.global_exists("lcdlib") and lcdlib.version < 1.01 then minetest.log("error", "[techage] Techage requires lcdlib version 1.01 or newer!") @@ -36,8 +36,8 @@ elseif minetest.global_exists("lcdlib") and lcdlib.version < 1.01 then elseif minetest.global_exists("safer_lua") and safer_lua.version < 1.01 then minetest.log("error", "[techage] Techage requires safer_lua version 1.01 or newer!") return -elseif minetest.global_exists("networks") and networks.version < 0.12 then - minetest.log("error", "[techage] Techage requires networks version 0.12 or newer!") +elseif minetest.global_exists("networks") and networks.version < 0.13 then + minetest.log("error", "[techage] Techage requires networks version 0.13 or newer!") return elseif minetest.global_exists("hyperloop") and hyperloop.version < 2.07 then minetest.log("error", "[techage] Techage requires hyperloop version 2.07 or newer!") diff --git a/techage/iron_age/meltingpot.lua b/techage/iron_age/meltingpot.lua index 0d3a406..ba0bb4d 100644 --- a/techage/iron_age/meltingpot.lua +++ b/techage/iron_age/meltingpot.lua @@ -395,6 +395,8 @@ minetest.register_node("techage:meltingpot_active", { can_dig = can_dig, + paramtype = "light", + use_texture_alpha = techage.CLIP, drop = "techage:meltingpot", is_ground_content = false, groups = {cracky = 3, not_in_creative_inventory=1}, diff --git a/techage/items/electronic.lua b/techage/items/electronic.lua index 1f54551..5139bec 100644 --- a/techage/items/electronic.lua +++ b/techage/items/electronic.lua @@ -51,11 +51,13 @@ minetest.register_craftitem("techage:ta5_aichip2", { techage.recipes.add("ta2_electronic_fab", { output = "techage:vacuum_tube 2", + waste = "basic_materials:empty_spool 1", input = {"default:glass 1", "basic_materials:copper_wire 1", "basic_materials:plastic_sheet 1", "techage:usmium_nuggets 1"} }) techage.recipes.add("ta3_electronic_fab", { output = "techage:vacuum_tube 2", + waste = "basic_materials:empty_spool 1", input = {"default:glass 1", "basic_materials:copper_wire 1", "basic_materials:plastic_sheet 1", "techage:usmium_nuggets 1"} }) @@ -81,17 +83,20 @@ techage.recipes.add("ta4_electronic_fab", { techage.recipes.add("ta4_electronic_fab", { output = "techage:ta4_leds 8", + waste = "basic_materials:empty_spool 1", input = {"basic_materials:plastic_sheet 4", "basic_materials:copper_wire 1", "techage:ta4_silicon_wafer 1"} }) techage.recipes.add("ta4_electronic_fab", { output = "techage:ta5_aichip 2", + waste = "basic_materials:empty_spool 2", input = {"techage:ta4_leds 8", "basic_materials:copper_wire 1", "basic_materials:gold_wire 1", "techage:ta4_silicon_wafer 1"}, ex_points = 10, }) techage.recipes.add("ta4_electronic_fab", { output = "techage:ta5_aichip2 2", + waste = "basic_materials:empty_spool 2", input = {"techage:ta4_leds 8", "basic_materials:copper_wire 1", "basic_materials:gold_wire 1", "techage:ta4_silicon_wafer 1"}, - ex_points = 50, + ex_points = 25, }) diff --git a/techage/items/moreblocks.lua b/techage/items/moreblocks.lua index 66c323a..f0ebddd 100644 --- a/techage/items/moreblocks.lua +++ b/techage/items/moreblocks.lua @@ -55,6 +55,8 @@ local NodeNames = { "techage:basalt_glass2", "techage:bauxite_stone", "techage:bauxite_cobble", + + "techage:cement_block", } if(minetest.get_modpath("moreblocks")) then diff --git a/techage/liquids/ta5_tank.lua b/techage/liquids/ta5_tank.lua index f8b470b..3c30610 100644 --- a/techage/liquids/ta5_tank.lua +++ b/techage/liquids/ta5_tank.lua @@ -26,7 +26,7 @@ local shared_tank = techage.shared_tank local menu = techage.menu local CAPACITY = 1000 -local EX_POINTS = 20 +local EX_POINTS = 15 minetest.register_node("techage:ta5_hl_tank", { description = S("TA5 Hyperloop Tank"), diff --git a/techage/locale/techage.de.tr b/techage/locale/techage.de.tr index 9def28a..ce57498 100644 --- a/techage/locale/techage.de.tr +++ b/techage/locale/techage.de.tr @@ -291,6 +291,10 @@ TA2 Cylinder=TA2 Zylinder ### detector.lua ### +Countdown=Countdown +Counts down the number of items passed through@nand only triggers an 'on' command when it reaches zero.=Zählt die Anzahl der durchlaufenen Elemente herunter@nund löst nur dann einen 'ON'-Befehl aus, wenn er Null erreicht. +Current countdown=Aktueller Zähler +Current countdown value.=Aktueller Zählerwert. TA4 Collider Detector=TA4 Collider Detektor TA4 Collider Detector Core=TA4 Collider Detektorkern TA4 Detector=TA4 Detektor @@ -500,8 +504,10 @@ Move=Bewege Move A-B=Bewege A-B Move B-A=Bewege B-A Move block height=Move Block Höhe +Object offset=Objekt Offset Stored=Gespeichert Value in the range of 0.0 to 1.0=Wert im Bereich von 0.0 bis 1.0 +Y-offset for non-player objects like vehicles (-0.5 to 0.5)=Y-Offset für Nicht-Spieler Objekte wie Fahrzeuge (-0.5 bis 0.5) ### flywheel.lua ### @@ -665,7 +671,6 @@ TA4 Hydrogen=TA4 Wasserstoff ### hyperloop.lua ### ### sensorchest.lua ### ### teleport.lua ### -### terminal.lua ### not connected=nicht verbunden @@ -746,7 +751,6 @@ Block has an@nadditional wrench menu=Block besitzt ein@nzusätzliches@nSchrauben ### lib.lua ### ### sensorchest.lua ### -### terminal.lua ### connected with=verbunden mit @@ -888,27 +892,22 @@ TA4 Streetlamp Solar Cell=TA4 Straßenlampen-Solarzelle ### minichest.lua ### -Test Chest= +Test Chest=Testkiste ### minitank.lua ### -Test Mini Tank= +Test Mini Tank=Testminitank ### movecontroller.lua ### Error: Invalid distance !!=Fehler: Ungültige Entfernung !! -Handover to A=Übergabe an A -Handover to B=Übergabe an B Move distance=Entfernung Move distance (A to B)=Entfernung (A nach B) -Number of the next movecontroller=Nummer des nächsten Move Controllers -Number of the previous movecontroller=Nummer des vorhergehenden Move Controllers -Object offset=Objekt Offset Operational mode=Betriebsmodus Reset=Rücksetzen Switch to the remote controlled 'move xyz' mode=Wechseln in den ferngesteuerten 'move xyz'-Modus +TA Rack and Pinion=TA Zahnstange TA4 Move Controller=TA4 Move Controller -Y-offset for non-player objects like vehicles (-0.5 to 0.5)=Y-Offset für Nicht-Spieler Objekte wie Fahrzeuge (-0.5 bis 0.5) ### node_detector.lua ### @@ -1170,6 +1169,8 @@ stopped=gestoppt Commands=Kommandos Cycle time=Zykluszeit Example:@n=Beispiel: +If 'yes' a received OFF command won't stop the sequencer=Bei 'yes' stoppt ein empfangener OFF-Befehl den Sequenzer nicht +Ignore OFF command=OFF-Befehl ignorieren Invalid command!=Ungültiges Kommando! Start=Start Stop=Stopp @@ -1192,8 +1193,8 @@ TA5 Fusion Reactor Shell=TA5 Fusionsreaktor Hülle ### signallamp.lua ### TA4 Wind Turbine Signal Lamp=TA4 Windkraftanlagenlampe -TechAge Signal Lamp=TechAge Signallampe -TechAge Signal Lamp 2 =TechAge Signallampe 2 +TechAge Color Lamp=TechAge Farblampe +TechAge Color Lamp 2=TechAge Farblampe 2 ### signallamp_2x.lua ### @@ -1401,7 +1402,6 @@ TA5 Teleport Block Items=TA5 Teleport Block Gegenstände Syntax error, try help=Syntax Fehler, nutze help TA3 Terminal=TA3 Terminal -TA4 Collider Terminal=TA4 Collider Terminal TA4 Terminal=TA4 Terminal commands like: help=Kommandos wie: help @@ -1511,4 +1511,11 @@ TA4 Collider Detector Worker=TA4 Collider Detektor Worker ##### not used anymore ##### +Handover to A=Übergabe an A +Handover to B=Übergabe an B +Number of the next movecontroller=Nummer des nächsten Move Controllers +Number of the previous movecontroller=Nummer des vorhergehenden Move Controllers +TechAge Signal Lamp=TechAge Signallampe +TechAge Signal Lamp 2 =TechAge Signallampe 2 +TA4 Collider Terminal=TA4 Collider Terminal Error: Max. length of the flight route exceeded !!=Fehler: Max. Flugstreckenlänge überschritten !! diff --git a/techage/locale/template.txt b/techage/locale/template.txt index 91e06c9..c75c27a 100644 --- a/techage/locale/template.txt +++ b/techage/locale/template.txt @@ -291,6 +291,10 @@ TA2 Cylinder= ### detector.lua ### +Countdown= +Counts down the number of items passed through@nand only triggers an 'on' command when it reaches zero.= +Current countdown= +Current countdown value.= TA4 Collider Detector= TA4 Collider Detector Core= TA4 Detector= @@ -500,8 +504,10 @@ Move= Move A-B= Move B-A= Move block height= +Object offset= Stored= Value in the range of 0.0 to 1.0= +Y-offset for non-player objects like vehicles (-0.5 to 0.5)= ### flywheel.lua ### @@ -665,7 +671,6 @@ TA4 Hydrogen= ### hyperloop.lua ### ### sensorchest.lua ### ### teleport.lua ### -### terminal.lua ### not connected= @@ -746,7 +751,6 @@ Block has an@nadditional wrench menu= ### lib.lua ### ### sensorchest.lua ### -### terminal.lua ### connected with= @@ -897,18 +901,13 @@ Test Mini Tank= ### movecontroller.lua ### Error: Invalid distance !!= -Handover to A= -Handover to B= Move distance= Move distance (A to B)= -Number of the next movecontroller= -Number of the previous movecontroller= -Object offset= Operational mode= Reset= Switch to the remote controlled 'move xyz' mode= +TA Rack and Pinion= TA4 Move Controller= -Y-offset for non-player objects like vehicles (-0.5 to 0.5)= ### node_detector.lua ### @@ -1170,6 +1169,8 @@ stopped= Commands= Cycle time= Example:@n= +If 'yes' a received OFF command won't stop the sequencer= +Ignore OFF command= Invalid command!= Start= Stop= @@ -1192,8 +1193,8 @@ TA5 Fusion Reactor Shell= ### signallamp.lua ### TA4 Wind Turbine Signal Lamp= -TechAge Signal Lamp= -TechAge Signal Lamp 2 = +TechAge Color Lamp= +TechAge Color Lamp 2= ### signallamp_2x.lua ### @@ -1401,7 +1402,6 @@ TA5 Teleport Block Items= Syntax error, try help= TA3 Terminal= -TA4 Collider Terminal= TA4 Terminal= commands like: help= diff --git a/techage/logic/sequencer2.lua b/techage/logic/sequencer2.lua index b861779..884ccbf 100644 --- a/techage/logic/sequencer2.lua +++ b/techage/logic/sequencer2.lua @@ -45,9 +45,18 @@ local WRENCH_MENU = { name = "cycletime", label = S("Cycle time"), tooltip = S("Timer cycle time (default: 100 ms)"), - default = "1", + default = "100ms", values = {0.1, 0.2, 0.5, 1.0, 2.0} }, + { + type = "dropdown", + choices = "no,yes", + name = "ignore_off", + label = S("Ignore OFF command"), + tooltip = S("If 'yes' a received OFF command won't stop the sequencer"), + default = "no", + values = {0, 1} + }, } local function cycle_time(pos) @@ -171,6 +180,7 @@ local function formspec(nvm, meta) return "size[10,8]" .. style .. + techage.wrench_image(9.3, -0.25) .. "tabheader[0,0;tab;edit,help;1;;true]" .. "label[0.1,-0.2;" .. S("Commands") .. ":]" .. textarea .. @@ -325,7 +335,7 @@ techage.register_node({"techage:ta4_sequencer"}, { mem.idx = tonumber(payload or 1) or 1 restart_timer(pos, 1) logic.infotext(M(pos), S("TA4 Sequencer"), S("running")) - elseif topic == "stop" or topic == "off" then + elseif topic == "stop" or (topic == "off" and M(pos):get_int("ignore_off") == 0) then nvm.running = false minetest.get_node_timer(pos):stop() logic.infotext(M(pos), S("TA4 Sequencer"), S("stopped")) diff --git a/techage/manuals/manual_ta1_DE.md b/techage/manuals/manual_ta1_DE.md index 4811439..b0de021 100644 --- a/techage/manuals/manual_ta1_DE.md +++ b/techage/manuals/manual_ta1_DE.md @@ -110,12 +110,6 @@ Block in verschiedenen Holzsorten zum Bauen des Mühlbachkanals. Dieser Block ei - -## - - - - ## Erze und Werkzeuge TA1 hat seine eigenen Werkzeuge wie Hammer und Kiessieb, aber auch der Minecart Hopper kann genutzt werden. diff --git a/techage/manuals/manual_ta3_DE.md b/techage/manuals/manual_ta3_DE.md index f62b3f3..cbe56b0 100644 --- a/techage/manuals/manual_ta3_DE.md +++ b/techage/manuals/manual_ta3_DE.md @@ -440,7 +440,7 @@ Damit die Minecarts automatisch wieder starten, müssen die Prellböcke mit Stat Der Tankwagen dient zum Transport von Flüssigkeiten. Es kann wie Tanks mit Pumpen gefüllt bzw. geleert werden. In beiden Fällen muss die gelbe Röhre von oben mit dem Tankwagen verbunden werden. -In den Tankwagen passen 100 Einheiten. +In den Tankwagen passen 200 Einheiten. [tank_cart|image] diff --git a/techage/manuals/manual_ta3_EN.md b/techage/manuals/manual_ta3_EN.md index b440e5f..3037dff 100644 --- a/techage/manuals/manual_ta3_EN.md +++ b/techage/manuals/manual_ta3_EN.md @@ -441,7 +441,7 @@ For the Minecarts to start again automatically, the bumper blocks must be config The tank truck is used to transport liquids. Like tanks, it can be filled with pumps or emptied. In both cases, the yellow tube must be connected to the tank truck from above. -100 units fit in the tank truck. +200 units fit in the tank truck. [tank_cart | image] diff --git a/techage/manuals/manual_ta4_DE.md b/techage/manuals/manual_ta4_DE.md index f17e60c..4ca0835 100644 --- a/techage/manuals/manual_ta4_DE.md +++ b/techage/manuals/manual_ta4_DE.md @@ -579,7 +579,6 @@ Anleitung: - mit den Menü-Tasten "Bewege A-B" sowie "Bewege B-A" kann die Bewegung getestet werden - man kann auch durch Wände oder andere Blöcke fliegen - auch die Zielposition für die Blöcke kann belegt sein. Die Blöcke werden in diesem Falle "unsichtbar" gespeichert. Dies ist für Schiebetüren und ähnliches gedacht -- Über das Gabelschlüssel-Menü kann im Controller auch ein "handover" programmiert werden. Durch Eingabe einer Blocknummer werden die Blöcke dann an den nächsten Move Controller übergeben. So lassen sich auch zusammenhängende Bewegungen über mehrere Move Controller realisieren. Der Move Controller unterstützt folgende techage Kommandos: diff --git a/techage/manuals/manual_ta4_EN.md b/techage/manuals/manual_ta4_EN.md index 9464e59..d034e18 100644 --- a/techage/manuals/manual_ta4_EN.md +++ b/techage/manuals/manual_ta4_EN.md @@ -570,7 +570,6 @@ Instructions: - The movement can be tested with the menu buttons "Move A-B" and "Move B-A" - you can also fly through walls or other blocks - The target position for the blocks can also be occupied. In this case, the blocks are saved "invisibly". This is intended for sliding doors and the like -- A "handover" can also be programmed in the controller via the open-ended wrench menu. By entering a block number, the blocks are then transferred to the next move controller. In this way, connected movements can also be implemented using several Move Controllers. The Move Controller supports the following techage commands: diff --git a/techage/manuals/manual_ta5_DE.md b/techage/manuals/manual_ta5_DE.md index 80bb36b..4a08af1 100644 --- a/techage/manuals/manual_ta5_DE.md +++ b/techage/manuals/manual_ta5_DE.md @@ -92,7 +92,7 @@ Die TA5 Hyperloop Kiste muss man dazu auf eine Hyperloop Junction stellen. Die K Für das Pairing musst du zuerst auf der einen Seite einen Namen für die Kiste eingeben, dann kannst du bei der anderen Kiste diesen Namen auswählen und so die beiden Blöcke verbinden. -Die Nutzung der TA5 Hyperloop Kiste benötigt 20 Erfahrungspunkte. +Die Nutzung der TA5 Hyperloop Kiste benötigt 15 Erfahrungspunkte. [ta5_chest|image] @@ -104,7 +104,7 @@ Den TA5 Hyperloop Tank muss man dazu auf eine Hyperloop Junction stellen. Der Ta Für das Pairing musst du zuerst auf der einen Seite einen Namen für den Tank eingeben, dann kannst du bei dem anderen Tank diesen Namen auswählen und so die beiden Blöcke verbinden. -Die Nutzung des TA5 Hyperloop Tanks benötigt 20 Erfahrungspunkte. +Die Nutzung des TA5 Hyperloop Tanks benötigt 15 Erfahrungspunkte. [ta5_tank|image] @@ -122,21 +122,21 @@ Der Plan rechts zeigt, wie die Blöcke genutzt werden können. ### TA5 Teleport Block Gegenstände / TA5 Teleport Block Items -Diese Teleport-Blöcke erlauben die Übertragung von Gegenständen und ersetzen somit eine Röhre. Dabei können Entfernungen von bis zu 200 Blöcken überbrückt werden. +Diese Teleport-Blöcke erlauben die Übertragung von Gegenständen und ersetzen somit eine Röhre. Dabei können Entfernungen von bis zu 500 Blöcken überbrückt werden. Ein Teleport-Block benötigt 12 ku Strom. -Für die Nutzung der Teleport-Blöcke werden 60 Erfahrungspunkte benötigt. +Für die Nutzung der Teleport-Blöcke werden 30 Erfahrungspunkte benötigt. [ta5_tele_tube|image] ### TA5 Teleport Block Flüssigkeiten / TA5 Teleport Block Liquids -Diese Teleport-Blöcke erlauben die Übertragung von Flüssigkeiten und ersetzen somit eine gelbe Leitung. Dabei können Entfernungen von bis zu 200 Blöcken überbrückt werden. +Diese Teleport-Blöcke erlauben die Übertragung von Flüssigkeiten und ersetzen somit eine gelbe Leitung. Dabei können Entfernungen von bis zu 500 Blöcken überbrückt werden. Ein Teleport-Block benötigt 12 ku Strom. -Für die Nutzung der Teleport-Blöcke werden 60 Erfahrungspunkte benötigt. +Für die Nutzung der Teleport-Blöcke werden 30 Erfahrungspunkte benötigt. [ta5_tele_pipe|image] @@ -144,7 +144,7 @@ Für die Nutzung der Teleport-Blöcke werden 60 Erfahrungspunkte benötigt. Die Hyperloop Teleport Blöcke erlauben den Aufbau von Hyperloop Netzwerk ohne Hyperloop-Röhren. -Die Nutzung der Hyperloop Teleport Blöcke benötigt 120 Erfahrungspunkte. +Die Nutzung der Hyperloop Teleport Blöcke benötigt 60 Erfahrungspunkte. ## Weitere TA5 Blöcke/Items @@ -162,6 +162,6 @@ Der TA5 KI Chip wird teilweise zur Herstellung von TA5 Blöcken benötigt. Der T ### TA5 KI Chip II / TA5 AI Chip II -Der TA5 KI Chip II wird zur Herstellung des TA5 Fusionsreaktors benötigt. Der TA5 KI Chip II kann nur auf der TA4 Elektronik Fab hergestellt werden. Dazu werden 50 Erfahrungspunkte benötigt. +Der TA5 KI Chip II wird zur Herstellung des TA5 Fusionsreaktors benötigt. Der TA5 KI Chip II kann nur auf der TA4 Elektronik Fab hergestellt werden. Dazu werden 25 Erfahrungspunkte benötigt. [ta5_aichip2|image] \ No newline at end of file diff --git a/techage/manuals/manual_ta5_EN.md b/techage/manuals/manual_ta5_EN.md index 83e0cad..8b01aa2 100644 --- a/techage/manuals/manual_ta5_EN.md +++ b/techage/manuals/manual_ta5_EN.md @@ -92,7 +92,7 @@ The TA5 Hyperloop Chest has to be placed on a Hyperloop Junction. The chest has For pairing you first have to enter a name for the chest on one side, then you can select this name for the other chest and thus connect the two blocks. -The use of the TA5 Hyperloop Chest requires 20 experience points. +The use of the TA5 Hyperloop Chest requires 15 experience points. [ta5_chest|image] @@ -104,7 +104,7 @@ The TA5 Hyperloop Tank has to be placed on a Hyperloop Junction.The tank has a s For pairing you first have to enter a name for the tank on one side, then you can select this name for the other tank and thus connect the two blocks. -The use of the TA5 Hyperloop Tank requires 20 experience points. +The use of the TA5 Hyperloop Tank requires 15 experience points. [ta5_tank|image] @@ -120,21 +120,21 @@ The map on the right shows how the blocks can be used. ### TA5 Teleport Block Items -These teleport blocks allow the transfer of items and thus replace a tube. Distances of up to 200 blocks can be bridged. +These teleport blocks allow the transfer of items and thus replace a tube. Distances of up to 500 blocks can be bridged. Each Teleport blocks requires 12 ku of electricity. -60 experience points are required to use the teleport blocks. +30 experience points are required to use the teleport blocks. [ta5_tele_tube|image] ### TA5 Teleport Block Liquids -These teleport blocks allow the transfer of liquids and thus replace a pipe. Distances of up to 200 blocks can be bridged. +These teleport blocks allow the transfer of liquids and thus replace a pipe. Distances of up to 500 blocks can be bridged. Each Teleport blocks requires 12 ku of electricity. -60 experience points are required to use the teleport blocks. +30 experience points are required to use the teleport blocks. [ta5_tele_pipe|image] @@ -142,7 +142,7 @@ Each Teleport blocks requires 12 ku of electricity. The Hyperloop Teleport Blocks allow the construction of a Hyperloop network without Hyperloop tubes. -The use of the Hyperloop Teleport Blocks requires 120 experience points. +The use of the Hyperloop Teleport Blocks requires 60 experience points. @@ -162,6 +162,6 @@ The TA5 AI Chip is partly required for the production of TA5 blocks. The TA5 AI ### TA5 AI Chip II -The TA5 AI Chip II is required to build the TA5 Fusion Reactor. The TA5 AI Chip II can only be manufactured at the TA4 Electronics Fab. This requires 50 experience points. +The TA5 AI Chip II is required to build the TA5 Fusion Reactor. The TA5 AI Chip II can only be manufactured at the TA4 Electronics Fab. This requires 25 experience points. [ta5_aichip2|image] diff --git a/techage/manuals/ta4_lua_controller_EN.md b/techage/manuals/ta4_lua_controller_EN.md index 2c937b3..59f9a5c 100644 --- a/techage/manuals/ta4_lua_controller_EN.md +++ b/techage/manuals/ta4_lua_controller_EN.md @@ -366,7 +366,9 @@ Please note, that this is not a technical distinction, only a logical. | "state" | one of: "on", "off" | State of a TA4 Button | | "fuel" | number | fuel value of a fuel consuming block | | "depth" | number | Read the current depth value of a quarry block (1..80) | -| "load" | number | Read the load value in percent (0..100) of a tank, silo, accu, or battery block, or from the Signs Bot Box. Silo and tank return two values: The percentage value and the absolute value in units.
Example: percent, absolute = $send_cmnd("223", "load") | +| "load" | number | Read the load value in percent (0..100) of a accu, or battery block. | +| "load" | number | Read the load value in percent (0..100) of a tank or silo.
Silo and tank return two values:
The percentage value and the absolute value in units.
Example: percent, absolute = $send_cmnd("223", "load") | +| "load" | number | Read the grid storage amount in percent (0..100) from a TA3 Power Terminal. | | "delivered" | number | Read the current delivered power value of a generator block. A power consuming block (accu) provides a negative value | | "flowrate" | Total flow rate in liquid units | Only for TA4 Pumps | | "action" | player-name, action-string | Only for Sensor Chests | diff --git a/techage/manuals/toc_DE.md b/techage/manuals/toc_DE.md index 4ede925..8b41dac 100644 --- a/techage/manuals/toc_DE.md +++ b/techage/manuals/toc_DE.md @@ -20,7 +20,6 @@ - [TA1 Schleusengriff / TA1 Sluice Handle](./manual_ta1_DE.md#ta1-schleusengriff--ta1-sluice-handle) - [TA1 Apfelholzbrett / TA1 Apple Wood Board](./manual_ta1_DE.md#ta1-apfelholzbrett--ta1-apple-wood-board) - [TA1 Apfel Mühlbachbrett / TA1 Apple Millrace Board](./manual_ta1_DE.md#ta1-apfel-mühlbachbrett--ta1-apple-millrace-board) - - [ ](./manual_ta1_DE.md#-) - [Erze und Werkzeuge](./manual_ta1_DE.md#erze-und-werkzeuge) - [Hammer](./manual_ta1_DE.md#hammer) - [Kiessieb / Gravel Sieve](./manual_ta1_DE.md#kiessieb--gravel-sieve) diff --git a/techage/move_controller/doorcontroller2.lua b/techage/move_controller/doorcontroller2.lua index 83ffbee..175cb0e 100644 --- a/techage/move_controller/doorcontroller2.lua +++ b/techage/move_controller/doorcontroller2.lua @@ -3,7 +3,7 @@ TechAge ======= - Copyright (C) 2020-2022 Joachim Stolberg + Copyright (C) 2020-2023 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -20,14 +20,68 @@ local S = techage.S local logic = techage.logic local fly = techage.flylib +local NUMSLOTS = 16 + local MarkedNodes = {} -- t[player] = {{entity, pos},...} local CurrentPos -- to mark punched entities -local function is_simple_node(name) - local ndef = minetest.registered_nodes[name] - return techage.can_dig_node(name, ndef) +-------------------------------------------------------------------------- +-- helper functions +-------------------------------------------------------------------------- +local function count_nodes(tbl, name) + if tbl[name] then + tbl[name] = tbl[name] + 1 + else + tbl[name] = 1 + end end +local function take_node(tbl, name) + if tbl[name] and tbl[name] > 0 then + tbl[name] = tbl[name] - 1 + return true + end +end + +local function next_node(tbl) + return function(tbl) + local name, cnt = next(tbl) + if cnt and cnt > 0 then + cnt = cnt - 1 + if cnt == 0 then + tbl[name] = nil + else + tbl[name] = cnt + end + return name + end + end, tbl +end + +local function get_new_nodename(item) + local name = item:get_name() + if name == "" then + return "air" + end + return name +end + +local function get_node_name(nvm, slot) + local pos = nvm.pos_list[slot] + if pos then + return techage.get_node_lvm(pos).name + end + return "unknown" +end + +local function is_simple_node(name) + local ndef = minetest.registered_nodes[name] + return name ~= "air" and techage.can_dig_node(name, ndef) +end + +-------------------------------------------------------------------------- +-- Marker +-------------------------------------------------------------------------- local function unmark_position(name, pos) pos = vector.round(pos) for idx,item in ipairs(MarkedNodes[name] or {}) do @@ -102,6 +156,9 @@ minetest.register_entity(":techage:marker", { end, }) +-------------------------------------------------------------------------- +-- formspec +-------------------------------------------------------------------------- local function formspec1(nvm, meta) local status = meta:get_string("status") local play_sound = dump(nvm.play_sound or false) @@ -109,8 +166,8 @@ local function formspec1(nvm, meta) "tabheader[0,0;tab;"..S("Ctrl,Inv")..";1;;true]".. "button[0.7,0.2;3,1;record;"..S("Record").."]".. "button[4.3,0.2;3,1;ready;"..S("Done").."]".. - "button[0.7,1.2;3,1;show;"..S("Set").."]".. - "button[4.3,1.2;3,1;hide;"..S("Remove").."]".. + "button[0.7,1.2;3,1;reset;"..S("Reset").."]".. + "button[4.3,1.2;3,1;exchange;"..S("Exchange").."]".. "checkbox[4.3,2.1;play_sound;"..S("with door sound")..";"..play_sound.."]".. "label[0.5,2.3;"..status.."]".. "list[current_player;main;0,3.3;8,4;]" @@ -136,10 +193,102 @@ local function play_sound(pos) max_hear_distance = 15}) end +-------------------------------------------------------------------------- +-- Configuration +-------------------------------------------------------------------------- +-- Store the current state of inventory and placed nodes +local function store_config(pos, nvm) + local meta = M(pos) + local inv = meta:get_inventory() + local item_list = inv:get_list("main") + local nodes = {exp_nodes = {}, inv_nodes = {}} + + nvm.pos_list = nvm.pos_list or {} + nvm.param2_list = nvm.param2_list or {} + + for idx = 1, NUMSLOTS do + local pos = nvm.pos_list[idx] + + if pos then + local param2 = nvm.param2_list[idx] or 0 + local item = item_list[idx] + if item and item:get_count() > 0 then + nodes.inv_nodes[idx] = {name = item:get_name(), param2 = param2} + end + + local node = techage.get_node_lvm(pos) + if is_simple_node(node.name) or node.name == "air" then + nodes.exp_nodes[idx] = techage.get_node_lvm(pos) + end + end + end + meta:set_string("stored_config", minetest.serialize(nodes)) +end + +-- Generate a table of currently available inventory and placed nodes +local function available_nodes(pos, nvm, item_list) + local nodes = {} + + for idx = 1, NUMSLOTS do + local item = item_list[idx] + if item and item:get_count() > 0 then + count_nodes(nodes, item:get_name()) + end + + local pos = nvm.pos_list[idx] + if pos then + local node = techage.get_node_lvm(pos) + if is_simple_node(node.name) then + count_nodes(nodes, node.name) + end + end + end + return nodes +end + +local function restore_config(pos, nvm) + local meta = M(pos) + local inv = meta:get_inventory() + local item_list = inv:get_list("main") + local stock = available_nodes(pos, nvm, item_list) + local nodes = minetest.deserialize(meta:get_string("stored_config")) or {} + + inv:set_list("main", {}) + item_list = inv:get_list("main") + + for idx, node in pairs(nodes.inv_nodes or {}) do + if take_node(stock, node.name) then + item_list[idx] = ItemStack(node.name) + end + end + inv:set_list("main", item_list) + + for idx, node in pairs(nodes.exp_nodes or {}) do + local pos = nvm.pos_list[idx] + if take_node(stock, node.name) then + local param2 = nvm.param2_list[idx] or 0 + fly.exchange_node(pos, node.name, param2) + nvm.expected_nodenames[idx] = node.name + else + fly.remove_node(pos) + nvm.expected_nodenames[idx] = "air" + end + end + + for name in next_node(stock) do + inv:add_item("main", ItemStack(name)) + end + + return true +end + +-------------------------------------------------------------------------- +-- Exchange nodes +-------------------------------------------------------------------------- local function exchange_node(pos, item, param2) local node = minetest.get_node_or_nil(pos) - if node and is_simple_node(node.name) then - if item and item:get_name() ~= "" and minetest.registered_nodes[item:get_name()] then + if node and is_simple_node(node.name) or node.name == "air" then + if item and is_simple_node(item:get_name()) then fly.exchange_node(pos, item:get_name(), param2) else fly.remove_node(pos) @@ -147,30 +296,48 @@ local function exchange_node(pos, item, param2) if not techage.is_air_like(node.name) then return ItemStack(node.name), node.param2 else - return ItemStack(), nil + return ItemStack(), param2 end end return item, param2 end +local function expected_node(pos, nvm, idx, force, new_nodename) + local expected_name = force and nvm.expected_nodenames[idx] or nil + if expected_name then + local node = techage.get_node_lvm(pos) + if expected_name == node.name then + nvm.expected_nodenames[idx] = new_nodename + return true + else + return false + end + end + nvm.expected_nodenames[idx] = new_nodename + return true +end + local function exchange_nodes(pos, nvm, slot, force) local meta = M(pos) local inv = meta:get_inventory() local item_list = inv:get_list("main") - local owner = meta:get_string("owner") local res = false nvm.pos_list = nvm.pos_list or {} nvm.param2_list = nvm.param2_list or {} + nvm.expected_nodenames = nvm.expected_nodenames or {} - for idx = (slot or 1), (slot or 16) do + for idx = (slot or 1), (slot or NUMSLOTS) do local pos = nvm.pos_list[idx] local item = item_list[idx] if pos then if (force == nil) + or (force == "exch") or (force == "dig" and item:get_count() == 0) or (force == "set" and item:get_count() > 0) then - item_list[idx], nvm.param2_list[idx] = exchange_node(pos, item, nvm.param2_list[idx]) + if expected_node(pos, nvm, idx, force, get_new_nodename(item)) then + item_list[idx], nvm.param2_list[idx] = exchange_node(pos, item, nvm.param2_list[idx]) + end res = true end end @@ -180,14 +347,6 @@ local function exchange_nodes(pos, nvm, slot, force) return res end -local function get_node_name(nvm, slot) - local pos = nvm.pos_list[slot] - if pos then - return techage.get_node_lvm(pos).name - end - return "unknown" -end - local function show_nodes(pos) local nvm = techage.get_nvm(pos) if not nvm.is_on then @@ -216,6 +375,17 @@ local function hide_nodes(pos) end end +local function exch_nodes(pos) + local nvm = techage.get_nvm(pos) + if nvm.play_sound then + minetest.sound_play("doors_door_open", { + pos = pos, + gain = 1, + max_hear_distance = 15}) + end + return exchange_nodes(pos, nvm) +end + minetest.register_node("techage:ta3_doorcontroller2", { description = S("TA3 Door Controller II"), tiles = { @@ -228,7 +398,7 @@ minetest.register_node("techage:ta3_doorcontroller2", { after_place_node = function(pos, placer, itemstack) local meta = M(pos) local inv = meta:get_inventory() - inv:set_size('main', 16) + inv:set_size('main', NUMSLOTS) logic.after_place_node(pos, placer, "techage:ta3_doorcontroller2", S("TA3 Door Controller II")) logic.infotext(meta, S("TA3 Door Controller II")) local nvm = techage.get_nvm(pos) @@ -252,11 +422,12 @@ minetest.register_node("techage:ta3_doorcontroller2", { elseif fields.record then local inv = meta:get_inventory() nvm.pos_list = nil - nvm.is_on = false meta:set_string("status", S("Recording...")) local name = player:get_player_name() minetest.chat_send_player(name, S("Click on all the blocks that are part of the door/gate")) + nvm.expected_nodenames = {} MarkedNodes[name] = {} + meta:set_string("stored_config", "") meta:set_string("formspec", formspec1(nvm, meta)) elseif fields.ready then local name = player:get_player_name() @@ -264,25 +435,24 @@ minetest.register_node("techage:ta3_doorcontroller2", { local text = #pos_list.." "..S("block positions are stored.") meta:set_string("status", text) nvm.pos_list = pos_list - nvm.is_on = true + nvm.expected_nodenames = {} unmark_all(name) + meta:set_string("stored_config", "") meta:set_string("formspec", formspec1(nvm, meta)) - elseif fields.show then - if show_nodes(pos) then - play_sound(pos) - meta:set_string("status", S("Blocks are back")) - meta:set_string("formspec", formspec1(nvm, meta)) - local name = player:get_player_name() - MarkedNodes[name] = nil - end - elseif fields.hide then - if hide_nodes(pos) then - play_sound(pos) - meta:set_string("status", S("Blocks are disappeared")) + elseif fields.exchange then + if exch_nodes(pos) then + store_config(pos, nvm) + meta:set_string("status", S("Blocks exchanged")) meta:set_string("formspec", formspec1(nvm, meta)) local name = player:get_player_name() MarkedNodes[name] = nil end + elseif fields.reset then + restore_config(pos, nvm) + meta:set_string("status", S("Blocks reset")) + meta:set_string("formspec", formspec1(nvm, meta)) + local name = player:get_player_name() + MarkedNodes[name] = nil elseif fields.play_sound then nvm.play_sound = fields.play_sound == "true" meta:set_string("formspec", formspec1(nvm, meta)) @@ -340,7 +510,7 @@ techage.register_node({"techage:ta3_doorcontroller2"}, { return show_nodes(pos) elseif topic == "exchange" then local nvm = techage.get_nvm(pos) - return exchange_nodes(pos, nvm, tonumber(payload)) + return exchange_nodes(pos, nvm, tonumber(payload), "exch") elseif topic == "set" then local nvm = techage.get_nvm(pos) return exchange_nodes(pos, nvm, tonumber(payload), "set") @@ -350,6 +520,9 @@ techage.register_node({"techage:ta3_doorcontroller2"}, { elseif topic == "get" then local nvm = techage.get_nvm(pos) return get_node_name(nvm, tonumber(payload)) + elseif topic == "reset" then + local nvm = techage.get_nvm(pos) + return restore_config(pos, nvm) end return false end, @@ -360,13 +533,16 @@ techage.register_node({"techage:ta3_doorcontroller2"}, { return show_nodes(pos) and 0 or 3 elseif topic == 9 and payload[1] == 0 then -- Exchange Block local nvm = techage.get_nvm(pos) - return exchange_nodes(pos, nvm, payload[2] or 1) and 0 or 3 + return exchange_nodes(pos, nvm, payload[2] or 1, "exch") and 0 or 3 elseif topic == 9 and payload[1] == 1 then -- Set Block local nvm = techage.get_nvm(pos) return exchange_nodes(pos, nvm, payload[2] or 1, "set") and 0 or 3 elseif topic == 9 and payload[1] == 2 then -- Dig Block local nvm = techage.get_nvm(pos) return exchange_nodes(pos, nvm, payload[2] or 1, "dig") and 0 or 3 + elseif topic == 9 and payload[1] == 3 then -- reset + local nvm = techage.get_nvm(pos) + return restore_config(pos, nvm) and 0 or 3 end return 2 end, diff --git a/techage/move_controller/movecontroller.lua b/techage/move_controller/movecontroller.lua index 2c25fb1..0eeb639 100644 --- a/techage/move_controller/movecontroller.lua +++ b/techage/move_controller/movecontroller.lua @@ -265,6 +265,34 @@ techage.register_node({"techage:ta4_movecontroller"}, { end, }) +minetest.register_node("techage:rack_and_pinion", { + description = S("TA Rack and Pinion"), + tiles = { + -- up, down, right, left, back, front + "default_steel_block.png", + "default_steel_block.png", + "default_steel_block.png", + "default_steel_block.png", + "default_steel_block.png", + "techage_rack_and_pinion.png", + }, + + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + { -6/32, -16/32, 14.1/32, 6/32, 16/32, 16/32}, + }, + }, + paramtype = "light", + use_texture_alpha = techage.CLIP, + sunlight_propagates = true, + paramtype2 = "facedir", + is_ground_content = false, + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_metal_defaults(), +}) + minetest.register_craft({ output = "techage:ta4_movecontroller", recipe = { @@ -273,3 +301,12 @@ minetest.register_craft({ {"group:wood", "basic_materials:gear_steel", "group:wood"}, }, }) + +minetest.register_craft({ + output = "techage:rack_and_pinion 10", + recipe = { + {"", "default:steel_ingot", ""}, + {"basic_materials:steel_bar", "default:steel_ingot", "basic_materials:steel_bar"}, + {"", "default:steel_ingot", ""}, + }, +}) diff --git a/techage/power/power_terminal2.lua b/techage/power/power_terminal2.lua index 564e2e5..b8bcd58 100644 --- a/techage/power/power_terminal2.lua +++ b/techage/power/power_terminal2.lua @@ -3,7 +3,7 @@ TechAge ======= - Copyright (C) 2019-2021 Joachim Stolberg + Copyright (C) 2019-2023 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -27,10 +27,11 @@ local control = networks.control local HELP = S([[Commands help . . . print this text -cls . . . . . clear screen -gen . . . . print all generators -sto . . . . . print all storage systems -con . . . . . print main consumers +cls . . . . clear screen +gen . . print generators +sto . . print storage systems +con1 . . print consumers with power consumption between 1 and 10 ku +con2 . . print consumers with power consumption with 10 ku or above ]]) local function row(num, label, data) @@ -41,7 +42,6 @@ local function row(num, label, data) "label[8.5,"..y..";" .. data .. "]" end - local function formspec1(pos, data) local mem = techage.get_mem(pos) local outdir = M(pos):get_int("outdir") @@ -94,12 +94,32 @@ local function formspec2(pos) "button[7.9,7.4;2,1;enter;"..S("Enter").."]" end +-------------------------------------------------------------------------------------- +--Overwrite networks.power.consume_power function +-------------------------------------------------------------------------------------- +local origin_consume_power = networks.power.consume_power + +function networks.power.consume_power(pos, tlib2, outdir, amount) + local nvm = techage.get_nvm(pos) + nvm.power_taken = origin_consume_power(pos, tlib2, outdir, amount) + return nvm.power_taken +end + +local function get_consumer_power_consumption(pos) + if pos then + local nvm = techage.get_nvm(pos) + if nvm.running or techage.needs_power(nvm) then + return nvm.power_taken or 0 + end + end + return 0 +end + local function generators(pos) local tbl = {} local outdir = M(pos):get_int("outdir") local resp = control.request(pos, Cable, outdir, "gen", "info") for _, item in ipairs(resp) do - local name = item.type .. " (" .. item.number .. ")" if item.running then local s = string.format("%s (%s): %s/%u ku (%s)", item.type, item.number, techage.round(item.provided), item.available, item.termpoint) @@ -119,26 +139,28 @@ local function storages(pos) local outdir = M(pos):get_int("outdir") local resp = control.request(pos, Cable, outdir, "sto", "info") for _, item in ipairs(resp) do - local name = item.type .. " (" .. item.number .. ")" - if item.running then - local s = string.format("%s (%s): %s/%s kud", - item.type, item.number, - techage.round(item.load / techage.CYCLES_PER_DAY), - techage.round(item.capa / techage.CYCLES_PER_DAY)) - tbl[#tbl + 1] = s - else - local s = string.format("%s (%s): %s/%s kud (off)", - item.type, item.number, - techage.round(item.load / techage.CYCLES_PER_DAY), - techage.round(item.capa / techage.CYCLES_PER_DAY)) - tbl[#tbl + 1] = s + -- TA4/TA5 heatexchangers are no storage systems + if item.capa and item.capa > 1 then + if item.running then + local s = string.format("%s (%s): %s/%s kud", + item.type, item.number, + techage.round(item.load / techage.CYCLES_PER_DAY), + techage.round(item.capa / techage.CYCLES_PER_DAY)) + tbl[#tbl + 1] = s + else + local s = string.format("%s (%s): %s/%s kud (off)", + item.type, item.number, + techage.round(item.load / techage.CYCLES_PER_DAY), + techage.round(item.capa / techage.CYCLES_PER_DAY)) + tbl[#tbl + 1] = s + end end end table.sort(tbl) return table.concat(tbl, "\n") end -local function consumers(pos) +local function consumers(pos, min, max) local tbl = {} local outdir = M(pos):get_int("outdir") local netw = networks.get_network_table(pos, Cable, outdir) or {} @@ -147,7 +169,17 @@ local function consumers(pos) if number then local name = techage.get_node_lvm(item.pos).name name = (minetest.registered_nodes[name] or {}).description or "unknown" - tbl[#tbl + 1] = name .. " (" .. number .. ")" + local taken = techage.round(get_consumer_power_consumption(item.pos)) + if taken > min and taken < max then + tbl[#tbl + 1] = string.format("%s (%s): %s ku", name, number, taken) + end + else + local name = techage.get_node_lvm(item.pos).name + name = (minetest.registered_nodes[name] or {}).description or "unknown" + local taken = techage.round(get_consumer_power_consumption(item.pos)) + if taken > min and taken < max then + tbl[#tbl + 1] = string.format("%s: %s ku", name, taken) + end end end table.sort(tbl) @@ -157,7 +189,7 @@ end local function output(pos, command, text) local meta = M(pos) text = meta:get_string("output") .. "\n$ " .. command .. "\n" .. (text or "") - text = text:sub(-2000,-1) + text = text:sub(-5000,-1) meta:set_string("output", text) end @@ -177,8 +209,10 @@ local function command(pos, nvm, command) output(pos, command, generators(pos)) elseif cmd == "sto" then output(pos, command, storages(pos)) - elseif cmd == "con" then - output(pos, command, consumers(pos)) + elseif cmd == "con1" then + output(pos, command, consumers(pos, 1, 10)) + elseif cmd == "con2" then + output(pos, command, consumers(pos, 9, 1000)) elseif command ~= "" then output(pos, command, "") end @@ -204,13 +238,18 @@ minetest.register_node("techage:ta3_power_terminal", { }, }, - after_place_node = function(pos) + after_place_node = function(pos, placer) M(pos):set_int("outdir", networks.side_to_outdir(pos, "B")) Cable:after_place_node(pos) M(pos):set_string("formspec", formspec1(pos)) + local number = techage.add_node(pos, "techage:ta3_power_terminal") + M(pos):set_string("node_number", number) + M(pos):set_string("owner", placer:get_player_name()) + M(pos):set_string("infotext", S("TA3 Power Terminal").." "..number) end, - after_dig_node = function(pos) + after_dig_node = function(pos, oldnode, oldmetadata, digger) Cable:after_dig_node(pos) + techage.remove_node(pos, oldnode, oldmetadata) techage.del_mem(pos) end, on_rightclick = function(pos, node, clicker) @@ -271,6 +310,28 @@ minetest.register_node("techage:ta3_power_terminal", { power.register_nodes({"techage:ta3_power_terminal"}, Cable, "con", {"B"}) +techage.register_node({"techage:ta3_power_terminal"}, { + on_recv_message = function(pos, src, topic, payload) + if topic == "load" then + local outdir = M(pos):get_int("outdir") + local value = networks.power.get_storage_percent(pos, Cable, outdir) + return techage.round(value) + else + return "unsupported" + end + end, + on_beduino_request_data = function(pos, src, topic, payload) + local nvm = techage.get_nvm(pos) + if topic == 134 then + local outdir = M(pos):get_int("outdir") + local value = networks.power.get_storage_percent(pos, Cable, outdir) + return 0, {math.floor(value + 0.5)} + else + return 2, "" + end + end, +}) + minetest.register_craft({ output = "techage:ta3_power_terminal", recipe = { diff --git a/techage/solar/minicell.lua b/techage/solar/minicell.lua index 6eedee5..a95839f 100644 --- a/techage/solar/minicell.lua +++ b/techage/solar/minicell.lua @@ -23,6 +23,7 @@ local PWR_CAPA = 2400 -- ticks (2s) with 1 ku ==> 80 min = 4 game days local Cable = techage.ElectricCable local power = networks.power +local control = networks.control local function node_timer(pos, elapsed) local nvm = techage.get_nvm(pos) @@ -46,7 +47,7 @@ local function node_timer(pos, elapsed) power.start_storage_calc(pos, Cable, 5) nvm.providing = true else - nvm.provided = power.provide_power(pos, Cable, 5, PWR_PERF) + nvm.provided = power.provide_power(pos, Cable, 5, PWR_PERF, 0.8, 1.0) nvm.capa = nvm.capa - nvm.provided end else @@ -105,6 +106,27 @@ minetest.register_node("techage:ta4_solar_minicell", { power.register_nodes({"techage:ta4_solar_minicell"}, Cable, "gen", {"D"}) +control.register_nodes({"techage:ta4_solar_minicell"}, { + on_receive = function(pos, tlib2, topic, payload) + end, + on_request = function(pos, tlib2, topic) + if topic == "info" then + local nvm = techage.get_nvm(pos) + local meta = M(pos) + return { + type = S("TA4 Streetlamp Solar Cell"), + number = meta:get_string("node_number") or "", + running = nvm.providing or false, + available = PWR_PERF, + provided = nvm.provided or 0, + termpoint = "80% - 100%", + } + end + return false + end, + } +) + techage.register_node({"techage:ta4_solar_minicell"}, { on_recv_message = function(pos, src, topic, payload) local nvm = techage.get_nvm(pos) diff --git a/techage/ta3_power/axle2power.lua b/techage/ta3_power/axle2power.lua index 39b8522..f6a0b3a 100644 --- a/techage/ta3_power/axle2power.lua +++ b/techage/ta3_power/axle2power.lua @@ -3,7 +3,7 @@ TechAge ======= - Copyright (C) 2019-2021 Joachim Stolberg + Copyright (C) 2019-2023 Joachim Stolberg AGPL v3 See LICENSE.txt for more information @@ -21,6 +21,7 @@ local S2P = minetest.string_to_pos local Cable = techage.ElectricCable local Axle = techage.Axle local power = networks.power +local control = networks.control local CYCLE_TIME = 2 local PWR_PERF = 24 @@ -45,9 +46,7 @@ local function node_timer_on(pos, elapsed) nvm.buffer = nvm.buffer + taken - 1 -- some loss if nvm.buffer >= PWR_PERF then - local tp1 = tonumber(meta:get_string("termpoint1")) - local tp2 = tonumber(meta:get_string("termpoint2")) - nvm.provided = power.provide_power(pos, Cable, outdir, PWR_PERF, tp1, tp2) + nvm.provided = power.provide_power(pos, Cable, outdir, PWR_PERF, 0.8, 1.0) nvm.load = power.get_storage_load(pos, Cable, outdir, PWR_PERF) nvm.buffer = nvm.buffer - nvm.provided end @@ -172,6 +171,27 @@ techage.register_node({"techage:ta2_generator_off", "techage:ta2_generator_on"}, power.register_nodes({"techage:ta2_generator_off", "techage:ta2_generator_on"}, Axle, "con", {"L"}) power.register_nodes({"techage:ta2_generator_off", "techage:ta2_generator_on"}, Cable, "gen", {"R"}) +control.register_nodes({"techage:ta2_generator_off", "techage:ta2_generator_on"}, { + on_receive = function(pos, tlib2, topic, payload) + end, + on_request = function(pos, tlib2, topic) + if topic == "info" then + local nvm = techage.get_nvm(pos) + local meta = M(pos) + return { + type = S("TA2 Power Generator"), + number = "---", + running = true, + available = PWR_PERF, + provided = nvm.provided or 0, + termpoint = "80% - 100%", + } + end + return false + end, + } +) + minetest.register_craft({ output = "techage:ta2_generator_off", recipe = { diff --git a/techage/ta3_power/tiny_generator.lua b/techage/ta3_power/tiny_generator.lua index 17ee65d..4f4847c 100644 --- a/techage/ta3_power/tiny_generator.lua +++ b/techage/ta3_power/tiny_generator.lua @@ -22,6 +22,7 @@ local fuel = techage.fuel local Pipe = techage.LiquidPipe local power = networks.power local liquid = networks.liquid +local control = networks.control local CYCLE_TIME = 2 local STANDBY_TICKS = 1 @@ -327,6 +328,27 @@ local liquid_def = { power.register_nodes({"techage:tiny_generator", "techage:tiny_generator_on"}, Cable, "gen", {"R"}) liquid.register_nodes({"techage:tiny_generator", "techage:tiny_generator_on"}, Pipe, "tank", nil, liquid_def) +control.register_nodes({"techage:tiny_generator", "techage:tiny_generator_on"}, { + on_receive = function(pos, tlib2, topic, payload) + end, + on_request = function(pos, tlib2, topic) + if topic == "info" then + local nvm = techage.get_nvm(pos) + local meta = M(pos) + return { + type = S("TA3 Tiny Power Generator"), + number = meta:get_string("node_number") or "", + running = techage.is_running(nvm) or false, + available = PWR_PERF, + provided = nvm.provided or 0, + termpoint = meta:get_string("termpoint"), + } + end + return false + end, + } +) + techage.register_node({"techage:tiny_generator", "techage:tiny_generator_on"}, { on_recv_message = function(pos, src, topic, payload) local nvm = techage.get_nvm(pos) diff --git a/techage/teleport/teleport_pipe.lua b/techage/teleport/teleport_pipe.lua index e07a167..84d19e0 100644 --- a/techage/teleport/teleport_pipe.lua +++ b/techage/teleport/teleport_pipe.lua @@ -28,8 +28,8 @@ local STANDBY_TICKS = 4 local COUNTDOWN_TICKS = 4 local CYCLE_TIME = 2 local PWR_NEEDED = 12 -local EX_POINTS = 60 -local MAX_DIST = 200 +local EX_POINTS = 30 +local MAX_DIST = 500 local DESCRIPTION = S("TA5 Teleport Block Liquids") local function formspec(self, pos, nvm) diff --git a/techage/teleport/teleport_tube.lua b/techage/teleport/teleport_tube.lua index 2f3c993..b064e7f 100644 --- a/techage/teleport/teleport_tube.lua +++ b/techage/teleport/teleport_tube.lua @@ -27,8 +27,8 @@ local STANDBY_TICKS = 4 local COUNTDOWN_TICKS = 4 local CYCLE_TIME = 2 local PWR_NEEDED = 12 -local EX_POINTS = 60 -local MAX_DIST = 200 +local EX_POINTS = 30 +local MAX_DIST = 500 local DESCRIPTION = S("TA5 Teleport Block Items") local function formspec(self, pos, nvm) diff --git a/techage/textures/techage_rack_and_pinion.png b/techage/textures/techage_rack_and_pinion.png new file mode 100644 index 0000000000000000000000000000000000000000..e01a0ce2088d116ad496dc6fd42dff9fad426e3c GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvi2$DvSN8&+z6lds+dI-SvyY#> z;O_0Gp{1j#qsw%qK?JCVu_VYZn8D%MjWi%f-P6S}MB{vN0s~{Jqk=(_14F8~f`g!j ox3;&lAO|axNMoRJ+d@f((m>sXU7VZPfm#?mUHx3vIVCg!0N+_8ZvX%Q literal 0 HcmV?d00001