From 28f722cf554be304cc1ac8f3eadb59640e725831 Mon Sep 17 00:00:00 2001 From: Joachim Stolberg Date: Fri, 3 Sep 2021 19:32:06 +0200 Subject: [PATCH] built on 03/09/2021 19:32:06 --- README.md | 7 + minecart/README.md | 4 +- minecart/buffer.lua | 15 +- minecart/doc.lua | 1 + minecart/init.lua | 2 +- minecart/locale/minecart.de.tr | 15 +- minecart/locale/template.txt | 6 + minecart/monitoring.lua | 27 ++ signs_bot/README.md | 14 +- signs_bot/cmd_soup.lua | 323 ++++++++++++++++++ signs_bot/cmd_trees.lua | 98 ++++++ signs_bot/duplicator.lua | 54 +-- signs_bot/init.lua | 4 +- signs_bot/locale/signs_bot.de.tr | 104 ++++-- signs_bot/locale/template.txt | 101 ++++-- signs_bot/mod.conf | 4 +- signs_bot/signs.lua | 50 +++ signs_bot/techage.lua | 4 +- signs_bot/textures/shrink.py | 16 - signs_bot/textures/shrink.sh | 2 + signs_bot/textures/signs_bot_and1.png | Bin 233 -> 171 bytes signs_bot/textures/signs_bot_and2.png | Bin 233 -> 171 bytes signs_bot/textures/signs_bot_and3.png | Bin 233 -> 171 bytes signs_bot/textures/signs_bot_and_inv.png | Bin 265 -> 202 bytes signs_bot/textures/signs_bot_base_front.png | Bin 504 -> 380 bytes signs_bot/textures/signs_bot_base_left.png | Bin 524 -> 406 bytes signs_bot/textures/signs_bot_base_right.png | Bin 547 -> 418 bytes signs_bot/textures/signs_bot_base_top.png | Bin 602 -> 465 bytes signs_bot/textures/signs_bot_bot_flap.png | Bin 897 -> 327 bytes signs_bot/textures/signs_bot_bot_flap_top.png | Bin 236 -> 215 bytes signs_bot/textures/signs_bot_changer1.png | Bin 209 -> 147 bytes signs_bot/textures/signs_bot_changer2.png | Bin 217 -> 155 bytes signs_bot/textures/signs_bot_changer3.png | Bin 215 -> 153 bytes signs_bot/textures/signs_bot_changer4.png | Bin 213 -> 151 bytes signs_bot/textures/signs_bot_chest_front.png | Bin 396 -> 348 bytes .../textures/signs_bot_ctrl_unit_inv.png | Bin 276 -> 214 bytes signs_bot/textures/signs_bot_delayer.png | Bin 224 -> 162 bytes signs_bot/textures/signs_bot_delayer_inv.png | Bin 251 -> 189 bytes .../textures/signs_bot_delayer_loaded.png | Bin 224 -> 162 bytes signs_bot/textures/signs_bot_delayer_on.png | Bin 224 -> 162 bytes signs_bot/textures/signs_bot_doc_image.png | Bin 33396 -> 8454 bytes signs_bot/textures/signs_bot_duplicator.png | Bin 522 -> 407 bytes signs_bot/textures/signs_bot_extender.png | Bin 200 -> 142 bytes signs_bot/textures/signs_bot_extender_inv.png | Bin 227 -> 166 bytes signs_bot/textures/signs_bot_extender_on.png | Bin 209 -> 150 bytes .../textures/signs_bot_extender_side.png | Bin 187 -> 125 bytes .../textures/signs_bot_form_level_bg.png | Bin 208 -> 146 bytes .../textures/signs_bot_form_level_fg.png | Bin 208 -> 146 bytes signs_bot/textures/signs_bot_form_mask.png | Bin 185 -> 97 bytes signs_bot/textures/signs_bot_missing_node.png | Bin 382 -> 317 bytes signs_bot/textures/signs_bot_robot.png | Bin 489 -> 388 bytes signs_bot/textures/signs_bot_robot_back.png | Bin 385 -> 188 bytes signs_bot/textures/signs_bot_robot_bottom.png | Bin 171 -> 113 bytes signs_bot/textures/signs_bot_robot_front.png | Bin 665 -> 304 bytes signs_bot/textures/signs_bot_robot_left.png | Bin 380 -> 219 bytes signs_bot/textures/signs_bot_robot_right.png | Bin 374 -> 212 bytes signs_bot/textures/signs_bot_robot_top.png | Bin 178 -> 120 bytes signs_bot/textures/signs_bot_sensor1.png | Bin 247 -> 185 bytes signs_bot/textures/signs_bot_sensor2.png | Bin 225 -> 163 bytes signs_bot/textures/signs_bot_sensor3.png | Bin 294 -> 232 bytes signs_bot/textures/signs_bot_sensor_bot.png | Bin 239 -> 177 bytes .../textures/signs_bot_sensor_bot_inv.png | Bin 281 -> 219 bytes .../textures/signs_bot_sensor_bot_on.png | Bin 239 -> 177 bytes signs_bot/textures/signs_bot_sensor_cart.png | Bin 354 -> 194 bytes .../textures/signs_bot_sensor_cart_inv.png | Bin 250 -> 188 bytes .../textures/signs_bot_sensor_cart_on.png | Bin 360 -> 194 bytes signs_bot/textures/signs_bot_sensor_crop.png | Bin 246 -> 184 bytes .../textures/signs_bot_sensor_crop_inv.png | Bin 281 -> 219 bytes .../textures/signs_bot_sensor_crop_on.png | Bin 246 -> 184 bytes signs_bot/textures/signs_bot_sensor_node.png | Bin 265 -> 203 bytes .../textures/signs_bot_sensor_node_inv.png | Bin 299 -> 237 bytes .../textures/signs_bot_sensor_node_on.png | Bin 265 -> 203 bytes signs_bot/textures/signs_bot_sign_add.png | Bin 325 -> 185 bytes .../textures/signs_bot_sign_add_cart.png | Bin 341 -> 188 bytes signs_bot/textures/signs_bot_sign_aspen.png | Bin 0 -> 165 bytes signs_bot/textures/signs_bot_sign_blank.png | Bin 225 -> 166 bytes signs_bot/textures/signs_bot_sign_cmnd.png | Bin 343 -> 183 bytes .../textures/signs_bot_sign_copy3x3x3.png | Bin 350 -> 192 bytes signs_bot/textures/signs_bot_sign_farming.png | Bin 254 -> 192 bytes signs_bot/textures/signs_bot_sign_flowers.png | Bin 373 -> 203 bytes signs_bot/textures/signs_bot_sign_left.png | Bin 256 -> 198 bytes signs_bot/textures/signs_bot_sign_pattern.png | Bin 334 -> 173 bytes signs_bot/textures/signs_bot_sign_right.png | Bin 256 -> 197 bytes signs_bot/textures/signs_bot_sign_soup.png | Bin 0 -> 165 bytes signs_bot/textures/signs_bot_sign_stop.png | Bin 343 -> 183 bytes signs_bot/textures/signs_bot_sign_take.png | Bin 323 -> 184 bytes .../textures/signs_bot_sign_take_cart.png | Bin 340 -> 185 bytes signs_bot/textures/signs_bot_sign_user.png | Bin 233 -> 174 bytes signs_bot/textures/signs_bot_sign_water.png | Bin 0 -> 166 bytes signs_bot/textures/signs_bot_timer.png | Bin 255 -> 193 bytes signs_bot/textures/signs_bot_timer_inv.png | Bin 294 -> 232 bytes signs_bot/textures/signs_bot_timer_on.png | Bin 255 -> 193 bytes signs_bot/textures/signs_bot_tool.png | Bin 540 -> 469 bytes .../textures/signs_bot_torch_animated.png | Bin 865 -> 515 bytes signs_bot/textures/signs_bot_torch_bottom.png | Bin 188 -> 156 bytes signs_bot/textures/signs_bot_torch_top.png | Bin 200 -> 179 bytes techage/basis/laser_lib.lua | 2 +- techage/energy_storage/heatexchanger2.lua | 3 + techage/logic/logic_block.lua | 38 ++- techage/logic/programmer.lua | 10 +- techage/ta1_watermill/sluice.lua | 4 + 101 files changed, 800 insertions(+), 108 deletions(-) create mode 100644 signs_bot/cmd_soup.lua create mode 100644 signs_bot/cmd_trees.lua delete mode 100644 signs_bot/textures/shrink.py create mode 100755 signs_bot/textures/shrink.sh create mode 100644 signs_bot/textures/signs_bot_sign_aspen.png create mode 100644 signs_bot/textures/signs_bot_sign_soup.png create mode 100644 signs_bot/textures/signs_bot_sign_water.png diff --git a/README.md b/README.md index ce00875..603c348 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,13 @@ ta4_jetpack requires the modpack 3d_armor. 3d_armor is itself a modpack and can' ### History +#### 2021-09-03 + +Updated Mods: +- techage +- minecart + + #### 2021-08-19 Changed Mods: diff --git a/minecart/README.md b/minecart/README.md index 0a9f5c2..cb4fd96 100644 --- a/minecart/README.md +++ b/minecart/README.md @@ -77,7 +77,8 @@ Introduction '' 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 ------ @@ -150,3 +151,4 @@ History 2020-11-12 V1.10 Make carts more robust against server lag 2021-04-10 V2.00 Complete revision to make carts robust against server load/lag, Speed limit signs and cart terminal added +2021-09-02 V2.01 Chat command /stopcart added \ No newline at end of file diff --git a/minecart/buffer.lua b/minecart/buffer.lua index 3c2100c..eb83091 100644 --- a/minecart/buffer.lua +++ b/minecart/buffer.lua @@ -35,12 +35,16 @@ local function remote_station_name(pos) if route and route.dest_pos then return M(route.dest_pos):get_string("name") end - return "none" end local function on_punch(pos, node, puncher) local name = M(pos):get_string("name") - M(pos):set_string("infotext", name..": "..S("connected to").." "..remote_station_name(pos)) + local dest = remote_station_name(pos) + if dest then + M(pos):set_string("infotext", name .. ": " .. S("connected to") .. " " .. dest) + else + M(pos):set_string("infotext", name .. ": " .. S("Not connected!")) + end M(pos):set_string("formspec", formspec(pos)) minetest.get_node_timer(pos):start(CYCLE_TIME) @@ -127,7 +131,12 @@ minetest.register_node("minecart:buffer", { M(pos):set_string("name", fields.name) M(pos):set_int("time", tonumber(fields.time) or 0) M(pos):set_string("formspec", formspec(pos)) - M(pos):set_string("infotext", fields.name.." "..S("connected to").." "..remote_station_name(pos)) + local dest = remote_station_name(pos) + if dest then + M(pos):set_string("infotext", fields.name .. ": " .. S("connected to") .. " " .. dest) + else + M(pos):set_string("infotext", fields.name .. ": " .. S("Not connected!")) + end minetest.get_node_timer(pos):start(CYCLE_TIME) end end, diff --git a/minecart/doc.lua b/minecart/doc.lua index 3f43b37..2d294fc 100644 --- a/minecart/doc.lua +++ b/minecart/doc.lua @@ -35,6 +35,7 @@ local summary_doc = table.concat({ S("10. Check the cart state via the chat command: /mycart \n '' is the cart number"), S("11. Drop items into the Minecart and punch the cart to start it."), S("12. Dig the cart with 'sneak+click' (as usual). The items will be drop down."), + S("13. To retrieve lost carts, use the chat command: /stopcart "), }, "\n") local cart_doc = S("Primary used to transport items. You can drop items into the Minecart and punch the cart to get started. Sneak+click the cart to get cart and items back") diff --git a/minecart/init.lua b/minecart/init.lua index b1e66b1..3785e99 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.00 +minecart.version = 2.01 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 4a52888..fdba00c 100644 --- a/minecart/locale/minecart.de.tr +++ b/minecart/locale/minecart.de.tr @@ -2,6 +2,7 @@ Station name=Stationsname Waiting time/sec=Wartezeit/s connected to=verbunden mit +Not connected!=Nicht verbunden! 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). @@ -12,9 +13,10 @@ Summary=Zusammenfassung 7. Optional: Configure the Minecart waiting time in both buffers. The Minecart will then start automatically after the configured time.=7. Optional: Konfiguriere die Wagenwartezeit in beiden Prellböcken. Der Wagen startet dann nach dieser Zeit automatisch. 8. Optional: Protect your rail network with the Protection Landmarks (one Landmark at least every 16 nodes/meters).=8. Optional: Schütze deine Schienen mit Hilfe der Meilensteine (ein Meilenstein mindestens alle 16 Blöcke). 9. Place a Minecart in front of the buffer and check whether it starts after the configured time.=9. Platziere einen Wagen direkt vor einem Prellbock und prüfe, ob er nach der konfigurierten Zeit startet. -10. Check the cart state via the chat command: /mycart @n '' is the cart number=Prüfe den Status des Wagen mit dem Chat Kommando: /mycart @n ist die Wagennummer +10. Check the cart state via the chat command: /mycart @n '' is the cart number=10. Prüfe den Status des Wagen mit dem Chat Kommando: /mycart @n ist die Wagennummer 11. Drop items into the Minecart and punch the cart to start it.=11: Lege Gegenstände in ein Wagen (Taste Q) und starte dann den Wagen durch Anklicken. -12. Dig the cart with 'sneak+click' (as usual). The items will be drop down.=10. Klicke mit gedrückter Shift-Taste auf den Wagen, um diesen zu entfernen. Die Gegenstände fallen dann zu Boden. +12. Dig the cart with 'sneak+click' (as usual). The items will be drop down.=12. Klicke mit gedrückter Shift-Taste auf den Wagen, um diesen zu entfernen. Die Gegenstände fallen dann zu Boden. +13. To retrieve lost carts, use the chat command: /stopcart =13. Um verirrte Waren zurückzuholen, verwende den Chat-Befehl: /stopcart Primary used to transport items. You can drop items into the Minecart and punch the cart to get started. Sneak+click the cart to get cart and items back=Primär für den Transport von Gegenständen genutzt. Du kannst Gegenstände in ein Cart legen (Taste Q) und dann den Wagen durch Anklicken starten. Klicke mit gedrückter Shift-Taste auf den Wagen, um Cart und Gegenstände zurückzuerhalten Used as buffer on both rail ends. Needed to be able to record the cart routes=Preckblöcke müssen an beiden Schienenenden platziert sein, so dass Aufzeichnungen der Strecke gemacht werden können. Protect your rails with the Landmarks (one Landmark at least every 16 blocks near the rail)=Schütze deine Schienen mit Hilfe der Meilensteine (ein Meilenstein mindestens alle 16 Blöcke der Strecke entlang) @@ -32,6 +34,10 @@ 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. +Cart=Wagen +stopped=gestoppt +is not existing!=existiert nicht! Enter cart number=Gebe Cart Nummer ein Save=Speichern [minecart] Area is protected!=[minecart] Bereich ist geschützt! @@ -52,8 +58,3 @@ Speed "4"=Tempo "4" No speed limit=Keine Geschwindigkeitsbegrenzung Cart List=Cart Liste Cart Terminal=Cart Terminal - - -##### not used anymore ##### - -Used to push a cart if the cart does not stop directly at a buffer. Block has to be placed below the rail.=Wird verwendet, um einen Wagen anzuschieben, wenn der Wagen nicht direkt an einem Puffer anhält. Der Block muss unter der Schiene platziert werden. diff --git a/minecart/locale/template.txt b/minecart/locale/template.txt index 7c64c6b..45ebd43 100644 --- a/minecart/locale/template.txt +++ b/minecart/locale/template.txt @@ -2,6 +2,7 @@ Station name= Waiting time/sec= connected to= +Not connected!= 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).= @@ -15,6 +16,7 @@ Summary= 10. Check the cart state via the chat command: /mycart @n '' is the cart number= 11. Drop items into the Minecart and punch the cart to start it.= 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 = Primary used to transport items. You can drop items into the Minecart and punch the cart to get started. Sneak+click the cart to get cart and items back= Used as buffer on both rail ends. Needed to be able to record the cart routes= Protect your rails with the Landmarks (one Landmark at least every 16 blocks near the rail)= @@ -32,6 +34,10 @@ 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.= +Cart= +stopped= +is not existing!= Enter cart number= Save= [minecart] Area is protected!= diff --git a/minecart/monitoring.lua b/minecart/monitoring.lua index 2377d8e..bde3fcd 100644 --- a/minecart/monitoring.lua +++ b/minecart/monitoring.lua @@ -243,6 +243,33 @@ minetest.register_chatcommand("mycart", { end }) +minetest.register_chatcommand("stopcart", { + params = "", + description = S("Stop amd return a missing/running cart."), + func = function(owner, param) + local userID = tonumber(param) + local player_pos = minetest.get_player_by_name(owner):get_pos() + if userID then + local data = minecart.get_cart_monitoring_data(owner, userID) + if data then + if data.objID and data.objID ~= 0 then + local entity = minetest.luaentities[data.objID] + if entity then -- cart entity running + minecart.entity_to_node(player_pos, entity) + end + else + local pos = data.last_pos or data.pos + local cargo, owner, userID = minecart.remove_nodecart(pos) + minecart.add_nodecart(player_pos, data.node_name, 0, cargo, owner, userID) + end + return true, S("Cart") .. " " .. userID .. " " .. S("stopped") + else + return false, S("Cart") .. " " .. userID .. " " .. S("is not existing!") + end + end + end +}) + function minecart.cmnd_cart_state(name, userID) local state, loc = get_cart_state_and_loc(name, userID, {x=0, y=0, z=0}) return state diff --git a/signs_bot/README.md b/signs_bot/README.md index fec834c..7f04f87 100644 --- a/signs_bot/README.md +++ b/signs_bot/README.md @@ -82,6 +82,7 @@ For all Inventory commands applies: If the inventory stack specified by i dig_right - remove block on the right dig_below - dig block under the robot dig_above - dig block above the robot + rotate_item - rotate a block in front of the robot place_sign - set sign place_sign_behind - put a sign behind the bot dig_sign - remove the sign @@ -96,7 +97,14 @@ For all Inventory commands applies: If the inventory stack specified by i pattern - save the blocks behind the shield (up to 5x3x3) as template copy - make a copy of "pattern". Size is e.g. 3x3 (see ingame help) punch_cart - Punch a rail cart to start it + add_compost - Put 2 leaves into the compost barrel + take_compost - Take a compost item from the barrel print - Output chat message for debug purposes + take_water - Take water with empty bucket + fill_cauldron - Fill the xdecor cauldron for a soup + take_soup - Take boiling soup into empty bowl from cauldron + flame_on - Make fire + flame_off - Put out the fire #### Flow control commands @@ -141,13 +149,14 @@ Or alternatively with the function at the end: return -- end of 'foo'. Jump back ### License -Copyright (C) 2019-2021 Joachim Stolberg +Copyright (C) 2019-2021 Joachim Stolberg +Copyright (C) 2021 Michal 'Micu' Cieslakiewicz (soup commands) Code: Licensed under the GNU GPL version 3 or later. See LICENSE.txt ### Dependencies default, farming, basic_materials, tubelib2 -optional: farming redo, node_io, doc, techage, minecart +optional: farming redo, node_io, doc, techage, minecart, xdecor, compost ### History @@ -173,4 +182,5 @@ optional: farming redo, node_io, doc, techage, minecart - 2021-03-14 v1.06 * Switch translation from intllib to minetest.translator - 2021-04-24 v1.07 * Adapted to minecart v2.0 - 2021-05-04 v1.08 * Add print command, improve error msg +- 2021-08-22 v1.09 * Add soup commands and signs, add aspen sign diff --git a/signs_bot/cmd_soup.lua b/signs_bot/cmd_soup.lua new file mode 100644 index 0000000..48054c3 --- /dev/null +++ b/signs_bot/cmd_soup.lua @@ -0,0 +1,323 @@ +--[[ + + Signs Bot + ========= + + Copyright (C) 2019-2021 Joachim Stolberg + Copyright (C) 2021 Michal 'Micu' Cieslakiewicz + + GPL v3 + See LICENSE.txt for more information + + Bot soup cooking commands + + Allows bot to use pot (xdecor:cauldron) to cook a vegetable soup + +]]-- + +if not minetest.global_exists("bucket") or not minetest.global_exists("fire") + or not minetest.global_exists("xdecor") then return end + +local M = minetest.get_meta + +-- Load support for I18n. +local S = signs_bot.S + +local lib = signs_bot.lib + +local bucket_empty, bucket_water = ItemStack("bucket:bucket_empty 1"), ItemStack("bucket:bucket_water 1") +local bowl_empty_farming, bowl_empty_xdecor = ItemStack("farming:bowl 1"), ItemStack("xdecor:bowl 1") +local bowl_soup = ItemStack("xdecor:bowl_soup 1") + +local function find_item_slot(base_pos, item) + local inv = M(base_pos):get_inventory() + local s = nil + for i = 1, 8 do + local t = inv:get_stack("main", i) + if t and t:get_name() == item:get_name() then + s = i + break + end + end + return s +end + +signs_bot.register_botcommand("take_water", { + mod = "soup", + params = "", + num_param = 1, + description = S("Take water into empty bucket when standing on a shore\n(use specified slot number or 0 for auto selection)"), + check = function(slot) + slot = tonumber(slot) + return slot and slot >= 0 and slot <= 8 + end, + cmnd = function(base_pos, mem, slot) + slot = tonumber(slot) + local pos = lib.dest_pos(mem.robot_pos, mem.robot_param2, { 0 }) + pos.y = pos.y - 1 + if not lib.not_protected(base_pos, pos) then + return signs_bot.ERROR, S("Error: Position protected") + end + local node = minetest.get_node_or_nil(pos) + if not node or node.name ~= "default:water_source" then + return signs_bot.ERROR, S("Error: No still water around") + end + local itemslot = slot + if slot == 0 then + itemslot = find_item_slot(base_pos, bucket_empty) + if not itemslot then + return signs_bot.ERROR, S("Error: No empty bucket in inventory") + end + end + local item = signs_bot.bot_inv_take_item(base_pos, itemslot, 1) + if not item or item:is_empty() or item:get_name() ~= bucket_empty:get_name() then + return signs_bot.ERROR, S("Error: No empty bucket in inventory slot " .. itemslot) + end + item = signs_bot.bot_inv_put_item(base_pos, slot, bucket_water) + if item:is_empty() then + minetest.remove_node(pos) + else + signs_bot.bot_inv_put_item(base_pos, itemslot, bucket_empty) + return signs_bot.ERROR, S("Error: No inventory space for full bucket") + end + return signs_bot.DONE + end, +}) + +signs_bot.register_botcommand("fill_cauldron", { + mod = "soup", + params = "", + num_param = 1, + description = S("Pour water from bucket to empty cauldron in front of a robot\n(use specified slot number or 0 for auto selection)"), + check = function(slot) + slot = tonumber(slot) + return slot and slot >= 0 and slot <= 8 + end, + cmnd = function(base_pos, mem, slot) + slot = tonumber(slot) + local pos = lib.dest_pos(mem.robot_pos, mem.robot_param2, { 0 }) + if not lib.not_protected(base_pos, pos) then + return signs_bot.ERROR, S("Error: Position protected") + end + local node = minetest.get_node_or_nil(pos) + if not node or node.name ~= "xdecor:cauldron_empty" then + return signs_bot.ERROR, S("Error: No empty cauldron in front of a robot") + end + local itemslot = slot + if slot == 0 then + itemslot = find_item_slot(base_pos, bucket_water) + if not itemslot then + return signs_bot.ERROR, S("Error: No full bucket in inventory") + end + end + local item = signs_bot.bot_inv_take_item(base_pos, itemslot, 1) + if not item or item:is_empty() or item:get_name() ~= bucket_water:get_name() then + return signs_bot.ERROR, S("Error: No full bucket in inventory slot " .. itemslot) + end + item = signs_bot.bot_inv_put_item(base_pos, slot, bucket_empty) + if item:is_empty() then + minetest.set_node(pos, { name = "xdecor:cauldron_idle", param2 = node.param2 }) + else + signs_bot.bot_inv_put_item(base_pos, itemslot, bucket_water) + return signs_bot.ERROR, S("Error: No inventory space for empty bucket") + end + return signs_bot.DONE + end, +}) + +signs_bot.register_botcommand("flame_on", { + mod = "soup", + params = "", + num_param = 0, + description = S("Set fire under cauldron (requires flammable material)\n(command is ignored when fire is already burning)"), + cmnd = function(base_pos, mem) + local pos = lib.dest_pos(mem.robot_pos, mem.robot_param2, { 0 }) + local fire_pos = { x = pos.x, y = pos.y - 1, z = pos.z } + local fuel_pos = { x = pos.x, y = pos.y - 2, z = pos.z } + if not (lib.not_protected(base_pos, pos) and lib.not_protected(base_pos, fire_pos) + and lib.not_protected(base_pos, fuel_pos)) then + return signs_bot.ERROR, S("Error: Position protected") + end + local node = minetest.get_node_or_nil(pos) + if not node or not node.name:find("xdecor:cauldron") then + return signs_bot.ERROR, S("Error: No cauldron in front of a robot") + end + local fire_node = minetest.get_node_or_nil(fire_pos) + if fire_node and fire_node.name:match("fire:[%w_]*flame") then + return signs_bot.DONE + elseif not fire_node or fire_node.name ~= "air" then + return signs_bot.ERROR, S("Error: No space for fire under cauldron") + end + local fuel_node = minetest.get_node_or_nil(fuel_pos) + if fuel_node and minetest.registered_nodes[fuel_node.name].on_ignite then + minetest.registered_nodes[fuel_node.name].on_ignite(fuel_pos) + elseif fuel_node and minetest.get_item_group(fuel_node.name, "flammable") >= 1 then + minetest.set_node(fire_pos, { name = "fire:basic_flame" }) + else + return signs_bot.ERROR, S("Error: No flammable material under cauldron") + end + return signs_bot.DONE + end, +}) + +signs_bot.register_botcommand("flame_off", { + mod = "soup", + params = "", + num_param = 0, + description = S("Put out (extinguish) fire under cauldron\n(command is ignored when there is no fire)"), + cmnd = function(base_pos, mem) + local pos = lib.dest_pos(mem.robot_pos, mem.robot_param2, { 0 }) + local fire_pos = { x = pos.x, y = pos.y - 1, z = pos.z } + if not (lib.not_protected(base_pos, pos) and lib.not_protected(base_pos, fire_pos)) then + return signs_bot.ERROR, S("Error: Position protected") + end + local node = minetest.get_node_or_nil(pos) + if not node or not node.name:find("xdecor:cauldron") then + return signs_bot.ERROR, S("Error: No cauldron in front of a robot") + end + local node = minetest.get_node_or_nil(fire_pos) + if node and node.name:match("fire:[%w_]*flame") then + minetest.remove_node(fire_pos) + end + return signs_bot.DONE + end, +}) + +signs_bot.register_botcommand("take_soup", { + mod = "soup", + params = "", + num_param = 1, + description = S("Take boiling soup into empty bowl from cauldron\nin front of a robot\n(use specified slot number or 0 for auto selection)"), + check = function(slot) + slot = tonumber(slot) + return slot and slot >= 0 and slot <= 8 + end, + cmnd = function(base_pos, mem, slot) + slot = tonumber(slot) + local pos = lib.dest_pos(mem.robot_pos, mem.robot_param2, { 0 }) + if not lib.not_protected(base_pos, pos) then + return signs_bot.ERROR, S("Error: Position protected") + end + local node = minetest.get_node_or_nil(pos) + if not node or node.name ~= "xdecor:cauldron_soup" then + return signs_bot.ERROR, S("Error: No cauldron with a soup in front of a robot") + end + local itemslot = slot + if slot == 0 then + itemslot = find_item_slot(base_pos, bowl_empty_xdecor) or find_item_slot(base_pos, bowl_empty_farming) + if not itemslot then + return signs_bot.ERROR, S("Error: No empty bowl in inventory") + end + end + local item = signs_bot.bot_inv_take_item(base_pos, itemslot, 1) + if not item or item:is_empty() or (item:get_name() ~= bowl_empty_farming:get_name() + and item:get_name() ~= bowl_empty_xdecor:get_name()) then + return signs_bot.ERROR, S("Error: No empty bowl in inventory slot " .. itemslot) + end + local item_full = signs_bot.bot_inv_put_item(base_pos, slot, bowl_soup) + if item_full:is_empty() then + minetest.set_node(pos, { name = "xdecor:cauldron_empty", param2 = node.param2 }) + else + signs_bot.bot_inv_put_item(base_pos, itemslot, item) + return signs_bot.ERROR, S("Error: No inventory space for full bowl") + end + return signs_bot.DONE + end, +}) + +local CMD_WATER = [[ +dig_sign 1 +move +take_water 1 +backward +place_sign 1 +turn_around +]] + +local CMD_SOUP = [[ +dig_sign 1 +move 2 +fill_cauldron 1 +flame_on +pause 11 +move_up +drop_items 1 2 +drop_items 1 3 +move_down +pause 6 +take_soup 4 +flame_off +backward +backward +place_sign 1 +turn_around +]] + +signs_bot.register_sign({ + name = "water", + description = S('Sign "take water"'), + commands = CMD_WATER, + image = "signs_bot_sign_water.png", +}) + + +signs_bot.register_sign({ + name = "soup", + description = S('Sign "cook soup"'), + commands = CMD_SOUP, + image = "signs_bot_sign_soup.png", +}) + +minetest.register_craft({ + output = "signs_bot:water", + recipe = { + {"group:wood", "bucket:bucket_empty", "group:wood"}, + {"dye:black", "default:stick", "dye:yellow"}, + {"dye:blue", "", ""} + } +}) + +minetest.register_craft({ + output = "signs_bot:soup", + recipe = { + {"group:wood", "xdecor:bowl", "group:wood"}, + {"dye:black", "default:stick", "dye:yellow"}, + {"dye:orange", "", ""} + } +}) + +if minetest.get_modpath("doc") then + doc.add_entry("signs_bot", "water", { + name = S("Sign 'take water'"), + data = { + item = "signs_bot:water", + text = table.concat({ + S("Used to take water into bucket."), + S("Place the sign on a shore, in front of the still water pool."), + S("Items in slots:"), + S(" 1 - empty bucket"), + S("The result is one bucket with water in selected inventory slot."), + S("When finished, the bot turns around."), + }, "\n") + }, + }) + doc.add_entry("signs_bot", "soup", { + name = S("Sign 'cook soup'"), + data = { + item = "signs_bot:soup", + text = table.concat({ + S("Used to cook a vegetable soup in cauldron."), + S("Cauldon should be empty and located above flammable material."), + S("Place the sign in front of the cauldron with one field space,"), + S("to prevent wooden sign from catching fire."), + S("Items in slots:"), + S(" 1 - water bucket"), + S(" 2 - vegetable #1 (i.e. tomato)"), + S(" 3 - vegetable #2 (i.e. carrot)"), + S(" 4 - empty bowl (from farming or xdecor mods)"), + S("The result is one bowl with vegetable soup in selected inventory slot."), + S("When finished, the bot turns around."), + }, "\n") + }, + }) +end diff --git a/signs_bot/cmd_trees.lua b/signs_bot/cmd_trees.lua new file mode 100644 index 0000000..3e6208b --- /dev/null +++ b/signs_bot/cmd_trees.lua @@ -0,0 +1,98 @@ +--[[ + + Signs Bot + ========= + + Copyright (C) 2019-2021 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + Bot tree cutting signs +]]-- + +-- Load support for I18n. +local S = signs_bot.S + +local CMNDS = [[-- Harvest pine/aspen trunks v1.0 + +-- Take dirt and saplings from chest +dig_sign 1 +move 1 +turn_right +take_item 99 0 +take_item 99 0 + +-- Goto trunk +turn_left +dig_front 0 0 +move 1 + +-- Climb up +repeat 10 + dig_above 0 + move_up + place_below 1 +end + +-- Climb down +repeat 10 + dig_below 1 + move_down +end + +-- Pickup saplings +repeat 4 + pickup_items 2 + turn_left +end + +-- Return dirt and saplings to chest +backward +plant_sapling 2 +turn_right +add_item 99 1 +add_item 99 2 + +-- Finish +turn_left +backward +place_sign 1 +turn_around]] + +local HELP = table.concat({ + S("Used to harvest an aspen or pine tree trunk"), + S("- Place the sign in front of the tree."), + S("- Place a chest to the right of the sign."), + S("- Put a dirt stack (10 items min.) into the chest."), + S("- Preconfigure slot 1 of the bot inventory with dirt"), + S("- Preconfigure slot 2 of the bot inventory with saplings"), +}, "\n") + + +signs_bot.register_signXL({ + name = "aspen", + description = S('Sign "aspen"'), + help_text = HELP, + commands = CMNDS, + image = "signs_bot_sign_aspen.png", +}) + +minetest.register_craft({ + output = "signs_bot:aspen 2", + recipe = { + {"group:wood", "default:stick", "group:wood"}, + {"dye:black", "default:stick", "dye:yellow"}, + {"dye:grey", "default:aspen_sapling", ""} + } +}) + +if minetest.get_modpath("doc") then + doc.add_entry("signs_bot", "aspen", { + name = S("Sign 'aspen'"), + data = { + item = "signs_bot:aspen", + text = HELP .. "\n", + }, + }) +end diff --git a/signs_bot/duplicator.lua b/signs_bot/duplicator.lua index fb6b942..34a5a37 100644 --- a/signs_bot/duplicator.lua +++ b/signs_bot/duplicator.lua @@ -63,38 +63,44 @@ local function allow_metadata_inventory_take(pos, listname, index, stack, player return stack:get_count() end +local function get_template_data(stack) + local name = stack:get_name() + local data = stack:get_meta():to_table().fields + + if name == "default:sign_user" or name == "signs_bot:sign_cmnd" then + return data.description, data.cmnd + end + if name == "default:book_written" then + return data.title, data.text + end +end + +local function get_dest_item(stack) + local name = stack:get_name() + if name == "signs_bot:sign_blank" or name == "signs_bot:sign_user" then + return ItemStack("signs_bot:sign_user") + end + if name == "signs_bot:sign_cmnd" then + return ItemStack("signs_bot:sign_cmnd") + end +end + local function move_to_output(pos) local inv = M(pos):get_inventory() local inp_stack = inv:get_stack("inp", 1) local temp_stack = inv:get_stack("temp", 1) local outp_stack = inv:get_stack("outp", 1) + local dest_item = get_dest_item(inp_stack) + local descr, cmnd = get_template_data(temp_stack) - if (inp_stack:get_name() == "signs_bot:sign_blank" - or inp_stack:get_name() == "signs_bot:sign_user") - and temp_stack:get_name() == "signs_bot:sign_cmnd" - and outp_stack:get_name() == "" then - local stack = ItemStack("signs_bot:sign_user") - stack:set_count(inp_stack:get_count()) - local meta = stack:get_meta() - local temp_meta = temp_stack:get_meta() - meta:set_string("cmnd", temp_meta:get_string("cmnd")) - meta:set_string("description", temp_meta:get_string("description")) + if dest_item and descr then + dest_item:set_count(inp_stack:get_count()) + local meta = dest_item:get_meta() + meta:set_string("description", descr) + meta:set_string("cmnd", cmnd) inp_stack:clear() inv:set_stack("inp", 1, inp_stack) - inv:set_stack("outp", 1, stack) - elseif (inp_stack:get_name() == "signs_bot:sign_blank" - or inp_stack:get_name() == "signs_bot:sign_user") - and temp_stack:get_name() == "default:book_written" - and outp_stack:get_name() == "" then - local stack = ItemStack("signs_bot:sign_user") - stack:set_count(inp_stack:get_count()) - local meta = stack:get_meta() - local temp_data = temp_stack:get_meta():to_table().fields - meta:set_string("cmnd", temp_data.text) - meta:set_string("description", temp_data.title) - inp_stack:clear() - inv:set_stack("inp", 1, inp_stack) - inv:set_stack("outp", 1, stack) + inv:set_stack("outp", 1, dest_item) end end diff --git a/signs_bot/init.lua b/signs_bot/init.lua index 98a8ea8..30e9c7c 100644 --- a/signs_bot/init.lua +++ b/signs_bot/init.lua @@ -15,7 +15,7 @@ signs_bot = {} -- Version for compatibility checks, see readme.md/history -signs_bot.version = 1.08 +signs_bot.version = 1.09 -- Test for MT 5.4 new string mode signs_bot.CLIP = minetest.features.use_texture_alpha_string_modes and "clip" or true @@ -52,6 +52,8 @@ dofile(MP.."/cmd_sign.lua") dofile(MP.."/cmd_pattern.lua") dofile(MP.."/cmd_farming.lua") dofile(MP.."/cmd_flowers.lua") +dofile(MP.."/cmd_soup.lua") +dofile(MP.."/cmd_trees.lua") dofile(MP.."/signal.lua") dofile(MP.."/extender.lua") diff --git a/signs_bot/locale/signs_bot.de.tr b/signs_bot/locale/signs_bot.de.tr index 1504914..36d62ef 100644 --- a/signs_bot/locale/signs_bot.de.tr +++ b/signs_bot/locale/signs_bot.de.tr @@ -5,7 +5,6 @@ ### basis.lua ### running=läuft -charging=aufladen stopped=gestoppt Off=Aus On=An @@ -15,7 +14,6 @@ Config=Konfig. Preassign slots items=Vorbelegungen Back=Zurück Robot Box=Roboterbox -no power=kein Strom Signs Bot Box=Roboter Box The Box is the housing of the bot.=Die Box ist das Gehäuse des Roboters. Place the box and start the bot by means of the 'On' button.=Platziere die Box und starte den Roboter über den "An" Button. @@ -43,6 +41,11 @@ Bot Sensor: Not connected=Bot Sensor: Nicht verbunden The Bot Sensor detects any bot and sends a signal, if a bot is nearby.=Der Roboter Sensor entdeckt jeden Roboter und sendet ein Signal, sofern ein Roboter in der Nähe ist. The sensor direction does not care.=Die Ausrichtung des Sensor spielt keine Rolle. +### bot_sensor.lua ### +### cart_sensor.lua ### + +the sensor range is one node/meter.=Der Sensorbereich ist einen Block/Meter groß. + ### cart_sensor.lua ### Cart Sensor: Connected with=Wagen Sensor: Verbunden mit @@ -51,11 +54,6 @@ Cart Sensor: Not connected=Wagen Sensor: Nicht verbunden The Cart Sensor detects and sends a signal, if a cart (Minecart) is nearby.=Der Wagen Sensor sendet ein Signal, sofern ein Wagen in der Nähe ist. The sensor has an active side (red) that must point to the rail/cart.=Der Sensor hat eine aktive Seite (rot), welche zu den Schienen zeigen muss. -### cart_sensor.lua ### -### bot_sensor.lua ### - -the sensor range is one node/meter.=Der Sensorbereich ist einen Block/Meter groß. - ### changer.lua ### Signs:=Zeichen: @@ -87,12 +85,6 @@ Sign 'farming'=Zeichen 'Farming' Used to harvest and seed a 3x3 field.=Benötigt um ein 3x3 Feld zu ernten und wieder zu sähen. The seed to be placed has to be in the first inventory slot of the bot.=Das Saatgut, dass gesät werden soll, muss sich an der 1. Position im Inventar befinden. -### cmd_farming.lua ### -### cmd_flowers.lua ### - -Place the sign in front of the field.=Platziere das Zeichen vor das Feld. -When finished, the bot turns.=Der Roboter dreht um, wenn er fertig ist. - ### cmd_flowers.lua ### Cutting flowers, leaves and tree blocks@nin front of the robot@non a 3x3 field.=Schneide Blumen, Blätter und Baumblöcke@nin einem 3x3 großem Feld@nvor dem Roboter. @@ -100,6 +92,12 @@ Sign "flowers"=Zeichen "Blumen" Sign 'flowers'=Zeichen 'Blumen' Used to cut flowers on a 3x3 field.=Benötigt um ein 3x3 Blumenfeld zu ernten. +### cmd_flowers.lua ### +### cmd_farming.lua ### + +Place the sign in front of the field.=Platziere das Zeichen vor das Feld. +When finished, the bot turns.=Der Roboter dreht um, wenn er fertig ist. + ### cmd_item.lua ### Take items from a chest like node@nand put it into the item inventory.@n is the inventory slot (1..8) or 0 for any one=Nehme Gegenstände aus der@nKiste oder dem Kisten-ähnlichen Block@nund tue diese in das eigene Inventar@nan der Position . Slot = (1..8)@noder 0 für irgend eine Position @@ -139,7 +137,6 @@ Use the pattern sign to mark the pattern.=Benutze das Vorlage-Zeichen und die Vo ### cmd_place.lua ### -Error: Position protected=Fehler: Position geschützt Place a block in front of the robot@n is the inventory slot (1..8)@n is one of: -1 0 +1=Setze einen Block vor den Roboter.@n ist die Position im@neigenen Inventar (1--8).@nFür ist zulässig: -1 0 +1 Place a block on the left side@n is the inventory slot (1..8)@n is one of: -1 0 +1=Setze einen Block links vorne.@n ist die Position im@neigenen Inventar (1--8).@nFür ist zulässig: -1 0 +1 Place a block on the right side@n is the inventory slot (1..8)@n is one of: -1 0 +1=Setze einen Block rechts vorne.@n ist die Position im@neigenen Inventar (1--8).@nFür ist zulässig: -1 0 +1 @@ -179,6 +176,64 @@ The 'command' sign can be programmed by the player.=Das 'Kommando' Zeichen kann Place the sign in front of you and use the node menu to program your sequence of bot commands.=Platziere das Zeichen vor dir und nutze das Zeichen-Menü, um die Kommando-Sequenz zu programmieren. The menu has an edit field for your commands and a help page with all available commands.=Das Menü hat ein Eingabefeld für deine Kommandos und eine Hilfeseite zu allen Kommandos. +### cmd_soup.lua ### + +Take water into empty bucket when standing on a shore@n(use specified slot number or 0 for auto selection)=Schöpfe Wasser mit einen leeren Eimer.@nDer Bot muss dazu am Wasser stehen. (verwende die Slot-Nummer@ndes Eimers oder 0 für eine automatische Auswahl) +Error: No still water around=Fehler: Kein stilles Wasser in der Nähe +Error: No empty bucket in inventory=Fehler: Kein leerer Eimer im Inventar +Error: No empty bucket in inventory slot =Fehler: Kein leerer Eimer in der Inventar Position +Error: No inventory space for full bucket=Fehler: Kein freier Inventarplatz für den vollen Eimer +Pour water from bucket to empty cauldron in front of a robot@n(use specified slot number or 0 for auto selection)=Gieße das Wasser aus dem Eimer in einen leeren Kessel (xdecor) vor dem Roboter@n(verwende die Slot-Nummer des Eimers oder 0 für eine automatische Auswahl) +Error: No empty cauldron in front of a robot=Fehler: Kein leerer Kessel vor dem Roboter +Error: No full bucket in inventory=Fehler: Kein voller Eimer im Inventar +Error: No full bucket in inventory slot =Fehler: Kein voller Eimer an der Inventarposition +Error: No inventory space for empty bucket=Fehler: Kein Platz im Inventar für den leeren Eimer +Set fire under cauldron (requires flammable material)@n(command is ignored when fire is already burning)=Mache Feuer unter dem Kessel (benötigt brennbares Material)@n(Befehl wird ignoriert, wenn Feuer bereits brennt) +Error: No cauldron in front of a robot=Fehler: Kein Kessel vor dem Roboter +Error: No space for fire under cauldron=Fehler: Kein Platz für das Feuer unter dem Kessel +Error: No flammable material under cauldron=Fehler: Kein brennbares Material unter dem Kessel +Put out (extinguish) fire under cauldron@n(command is ignored when there is no fire)=Das Feuer löschen unter dem Kessel@n(Befehl wird ignoriert, wenn kein Feuer vorhanden ist) +Take boiling soup into empty bowl from cauldron@nin front of a robot@n(use specified slot number or 0 for auto selection)=Die kochende Suppe aus im Kessel in eine leere Schüssel tun.@n(verwende die Slot-Nummer der Schüssel oder 0 für eine automatische Auswahl) +Error: No cauldron with a soup in front of a robot=Fehler: Kein Kessel mit Suppe vor dem Roboter +Error: No empty bowl in inventory=Fehler: Keine leere Schüssel im Inventar +Error: No empty bowl in inventory slot =Fehler: Keine leere Schüssel in der angegebenen Inventarposition +Error: No inventory space for full bowl=Fehler: Kein Platz im Inventar für die Schüssel +Sign "take water"=Zeichen "Schöpfe Wasser" +Sign "cook soup"=Zeichen "Koche Suppe" +Sign 'take water'=Zeichen 'Schöpfe Wasser' +Used to take water into bucket.=Wird verwendet, um Wasser in den Eimer zu schöpfen. +Place the sign on a shore, in front of the still water pool.=Platziere das Schild am Ufer des Wassers +Items in slots:=Gegenstände im Inventar: + 1 - empty bucket= 1 - leerer Eimer +The result is one bucket with water in selected inventory slot.=Das Ergebnis ist ein Eimer mit Wasser an der ausgewählten Inventarposition. +When finished, the bot turns around.=Wenn er fertig ist, dreht sich der Bot um. +Sign 'cook soup'=Zeichen 'Koche Suppe' +Used to cook a vegetable soup in cauldron.=Wird verwendet, um eine vegetarische Suppe im Kessel zu kochen. +Cauldon should be empty and located above flammable material.=Der Kessel sollte leer sein und sich über brennbarem Material befinden. +Place the sign in front of the cauldron with one field space,=Platziere das Schild vor dem Kessel mit einem Feld Abstand, +to prevent wooden sign from catching fire.=um zu verhindern, dass das Holzschild Feuer fängt. + 1 - water bucket= 2 - Wassereimer + 2 - vegetable #1 (i.e. tomato)= 2 - Gemüse #1 (bspw. Tomate) + 3 - vegetable #2 (i.e. carrot)= 3 - Gemüse #2 (bspw. Zwiebel) + 4 - empty bowl (from farming or xdecor mods)= 4 - Leere Schüssel (Von der Mod farming oder xdecor) +The result is one bowl with vegetable soup in selected inventory slot.=Das Ergebnis ist eine Schüssel mit Gemüsesuppe an der ausgewählten Inventarposition. + +### cmd_soup.lua ### +### cmd_place.lua ### + +Error: Position protected=Fehler: Position geschützt + +### cmd_trees.lua ### + +Used to harvest an aspen or pine tree trunk=Wird verwendet, um einen Espen- oder Kiefernstamm zu ernten +- Place the sign in front of the tree.=- Setze das Zeichen vor den Baum. +- Place a chest to the right of the sign.=- Setze eine Kiste rechts neben das Zeichen. +- Put a dirt stack (10 items min.) into the chest.=- Lege einen Stapel (>10) Erde (dirt) in die Kiste. +- Preconfigure slot 1 of the bot inventory with dirt=Pos. 1 des Bot-Inventars mit Erde (dirt) vorkonfigurieren +- Preconfigure slot 2 of the bot inventory with saplings=Pos. 2 des Bot-Inventars mit einem Setzling vorkonfigurieren +Sign "aspen"=Zeichen "Espe" +Sign 'aspen'=Zeichen 'Espe' + ### commands.lua ### commands:=Kommandos: @@ -345,6 +400,11 @@ inputs=Eingängen Signal AND=Signal UND Signal is sent, if all input signals are received.=Signal wird gesendet, wenn all Eingangssignale empfangen wurden. +### logic_and.lua ### +### timer.lua ### + +Connected with=Verbunden mit + ### node_sensor.lua ### Node Sensor: Connected with =Block Sensor: Verbunden mit @@ -363,6 +423,8 @@ The sensor has an active side (red) that must point to the observed area.=Der Se ### signs.lua ### +Instructions:=Anweisungen: +Code=Code Sign "turn right"=Zeichen "rechts drehen" Sign "turn left"=Zeichen "links drehen" Sign "take item"=Zeichen "Nehme Gegenstand" @@ -382,11 +444,17 @@ The Bot takes items out of a minecart in front of it, pushes the cart and then t ### techage.lua ### +no power=kein Strom Ignite the techage charcoal lighter=Zünde den Holzkohle-Anzünder an Turns the bot off if the@nbattery power is below the@ngiven value in percent (1..99)=Schalte den Bot aus,@nwenn die Batterieladung kleiner@nist als der angegebene Wert@nin Prozent (1.99) fully charged=voll geladen Sends a techage command@nto a given node. @nReceiver is addressed by@nthe techage node number.@nFor commands with two or more @nwords, use the '*' character @ninstead of spaces, e.g.: @nsend_cmnd 3465 pull*default:dirt*2=Sende ein techage Kommando@nan einen Block mit der@nangegebenen Blocknummer.@nFür Kommandos mit zwei oder mehr @nWörtern verwende das Zeichen '*' @nanstelle des Leerzeichens, wie bspw.:@nsend_cmnd 3465 pull*default:dirt*2 +### techage.lua ### +### basis.lua ### + +charging=aufladen + ### timer.lua ### Bot Timer=Roboter Timer @@ -400,14 +468,6 @@ Can be programmed with a time in seconds, e.g. to start the bot cyclically.=Kann Start=Start -### timer.lua ### -### logic_and.lua ### - -Connected with=Verbunden mit - ### tool.lua ### Sensor Connection Tool=Sensor Verbindungswerkzeug - - -##### not used anymore ##### diff --git a/signs_bot/locale/template.txt b/signs_bot/locale/template.txt index f12d7e3..75f90ec 100644 --- a/signs_bot/locale/template.txt +++ b/signs_bot/locale/template.txt @@ -5,7 +5,6 @@ ### basis.lua ### running= -charging= stopped= Off= On= @@ -15,7 +14,6 @@ Config= Preassign slots items= Back= Robot Box= -no power= Signs Bot Box= The Box is the housing of the bot.= Place the box and start the bot by means of the 'On' button.= @@ -43,6 +41,11 @@ Bot Sensor: Not connected= The Bot Sensor detects any bot and sends a signal, if a bot is nearby.= The sensor direction does not care.= +### bot_sensor.lua ### +### cart_sensor.lua ### + +the sensor range is one node/meter.= + ### cart_sensor.lua ### Cart Sensor: Connected with= @@ -51,11 +54,6 @@ Cart Sensor: Not connected= The Cart Sensor detects and sends a signal, if a cart (Minecart) is nearby.= The sensor has an active side (red) that must point to the rail/cart.= -### cart_sensor.lua ### -### bot_sensor.lua ### - -the sensor range is one node/meter.= - ### changer.lua ### Signs:= @@ -87,12 +85,6 @@ Sign 'farming'= Used to harvest and seed a 3x3 field.= The seed to be placed has to be in the first inventory slot of the bot.= -### cmd_farming.lua ### -### cmd_flowers.lua ### - -Place the sign in front of the field.= -When finished, the bot turns.= - ### cmd_flowers.lua ### Cutting flowers, leaves and tree blocks@nin front of the robot@non a 3x3 field.= @@ -100,6 +92,12 @@ Sign "flowers"= Sign 'flowers'= Used to cut flowers on a 3x3 field.= +### cmd_flowers.lua ### +### cmd_farming.lua ### + +Place the sign in front of the field.= +When finished, the bot turns.= + ### cmd_item.lua ### Take items from a chest like node@nand put it into the item inventory.@n is the inventory slot (1..8) or 0 for any one= @@ -139,7 +137,6 @@ Use the pattern sign to mark the pattern.= ### cmd_place.lua ### -Error: Position protected= Place a block in front of the robot@n is the inventory slot (1..8)@n is one of: -1 0 +1= Place a block on the left side@n is the inventory slot (1..8)@n is one of: -1 0 +1= Place a block on the right side@n is the inventory slot (1..8)@n is one of: -1 0 +1= @@ -179,6 +176,64 @@ The 'command' sign can be programmed by the player.= Place the sign in front of you and use the node menu to program your sequence of bot commands.= The menu has an edit field for your commands and a help page with all available commands.= +### cmd_soup.lua ### + +Take water into empty bucket when standing on a shore@n(use specified slot number or 0 for auto selection)= +Error: No still water around= +Error: No empty bucket in inventory= +Error: No empty bucket in inventory slot = +Error: No inventory space for full bucket= +Pour water from bucket to empty cauldron in front of a robot@n(use specified slot number or 0 for auto selection)= +Error: No empty cauldron in front of a robot= +Error: No full bucket in inventory= +Error: No full bucket in inventory slot = +Error: No inventory space for empty bucket= +Set fire under cauldron (requires flammable material)@n(command is ignored when fire is already burning)= +Error: No cauldron in front of a robot= +Error: No space for fire under cauldron= +Error: No flammable material under cauldron= +Put out (extinguish) fire under cauldron@n(command is ignored when there is no fire)= +Take boiling soup into empty bowl from cauldron@nin front of a robot@n(use specified slot number or 0 for auto selection)= +Error: No cauldron with a soup in front of a robot= +Error: No empty bowl in inventory= +Error: No empty bowl in inventory slot = +Error: No inventory space for full bowl= +Sign "take water"= +Sign "cook soup"= +Sign 'take water'= +Used to take water into bucket.= +Place the sign on a shore, in front of the still water pool.= +Items in slots:= + 1 - empty bucket= +The result is one bucket with water in selected inventory slot.= +When finished, the bot turns around.= +Sign 'cook soup'= +Used to cook a vegetable soup in cauldron.= +Cauldon should be empty and located above flammable material.= +Place the sign in front of the cauldron with one field space,= +to prevent wooden sign from catching fire.= + 1 - water bucket= + 2 - vegetable #1 (i.e. tomato)= + 3 - vegetable #2 (i.e. carrot)= + 4 - empty bowl (from farming or xdecor mods)= +The result is one bowl with vegetable soup in selected inventory slot.= + +### cmd_soup.lua ### +### cmd_place.lua ### + +Error: Position protected= + +### cmd_trees.lua ### + +Used to harvest an aspen or pine tree trunk= +- Place the sign in front of the tree.= +- Place a chest to the right of the sign.= +- Put a dirt stack (10 items min.) into the chest.= +- Preconfigure slot 1 of the bot inventory with dirt= +- Preconfigure slot 2 of the bot inventory with saplings= +Sign "aspen"= +Sign 'aspen'= + ### commands.lua ### commands:= @@ -345,6 +400,11 @@ inputs= Signal AND= Signal is sent, if all input signals are received.= +### logic_and.lua ### +### timer.lua ### + +Connected with= + ### node_sensor.lua ### Node Sensor: Connected with = @@ -363,6 +423,8 @@ The sensor has an active side (red) that must point to the observed area.= ### signs.lua ### +Instructions:= +Code= Sign "turn right"= Sign "turn left"= Sign "take item"= @@ -382,11 +444,17 @@ The Bot takes items out of a minecart in front of it, pushes the cart and then t ### techage.lua ### +no power= Ignite the techage charcoal lighter= Turns the bot off if the@nbattery power is below the@ngiven value in percent (1..99)= fully charged= Sends a techage command@nto a given node. @nReceiver is addressed by@nthe techage node number.@nFor commands with two or more @nwords, use the '*' character @ninstead of spaces, e.g.: @nsend_cmnd 3465 pull*default:dirt*2= +### techage.lua ### +### basis.lua ### + +charging= + ### timer.lua ### Bot Timer= @@ -400,11 +468,6 @@ Can be programmed with a time in seconds, e.g. to start the bot cyclically.= Start= -### timer.lua ### -### logic_and.lua ### - -Connected with= - ### tool.lua ### Sensor Connection Tool= diff --git a/signs_bot/mod.conf b/signs_bot/mod.conf index fb50f78..7e84aab 100644 --- a/signs_bot/mod.conf +++ b/signs_bot/mod.conf @@ -1,4 +1,4 @@ name=signs_bot depends = default,farming,basic_materials,tubelib2 -optional_depends = node_io,techage,doc,minecart -description = A robot controlled by signs \ No newline at end of file +optional_depends = node_io,techage,doc,minecart,bucket,fire,xdecor +description = A robot controlled by signs diff --git a/signs_bot/signs.lua b/signs_bot/signs.lua index def287c..aa20777 100644 --- a/signs_bot/signs.lua +++ b/signs_bot/signs.lua @@ -24,6 +24,18 @@ local function formspec(cmnd) "label[0.2,0;"..cmnd.."]" end +local function formspecXL(help_text, bot_cmnds) + help_text = help_text or "no help" + bot_cmnds = minetest.formspec_escape(bot_cmnds) + return "size[9,8]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "label[0,0;" .. S("Instructions:") .. "]" .. + "label[0.2,0.6;" .. help_text .. "]" .. + "textarea[0.3,4.0;9,4.9;code;" .. S("Code") .. ":;" .. bot_cmnds .. "]" +end + local function register_sign(def) minetest.register_node("signs_bot:"..def.name, { description = def.description, @@ -61,7 +73,45 @@ local function register_sign(def) }) end +local function register_signXL(def) + minetest.register_node("signs_bot:"..def.name, { + description = def.description, + inventory_image = def.image, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + { -1/16, -8/16, -1/16, 1/16, 4/16, 1/16}, + { -6/16, -5/16, -2/16, 6/16, 3/16, -1/16}, + }, + }, + paramtype2 = "facedir", + tiles = { + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png^"..def.image, + }, + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("signs_bot_cmnd", def.commands) + meta:set_string("formspec", formspecXL(def.help_text, def.commands)) + meta:set_string("infotext", def.description) + end, + on_rotate = screwdriver.disallow, + paramtype = "light", + use_texture_alpha = signs_bot.CLIP, + sunlight_propagates = true, + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, sign_bot_sign = 1}, + sounds = default.node_sound_wood_defaults(), + }) +end + signs_bot.register_sign = register_sign +signs_bot.register_signXL = register_signXL diff --git a/signs_bot/techage.lua b/signs_bot/techage.lua index e4e7def..006a29c 100644 --- a/signs_bot/techage.lua +++ b/signs_bot/techage.lua @@ -167,9 +167,9 @@ send_cmnd 3465 pull*default:dirt*2]]), command = command:gsub("*", " ") address = tostring(tonumber(address)) local meta = minetest.get_meta(base_pos) - local number = meta:get_int("number") or 0 + local number = tostring(meta:get_int("number") or 0) local topic, payload = unpack(string.split(command, " ", false, 1)) - techage.send_multi(number, address, topic, payload) + techage.send_single(number, address, topic, payload) return signs_bot.DONE end, }) diff --git a/signs_bot/textures/shrink.py b/signs_bot/textures/shrink.py deleted file mode 100644 index 96863b9..0000000 --- a/signs_bot/textures/shrink.py +++ /dev/null @@ -1,16 +0,0 @@ -import os, fnmatch - - -print ">>> Convert" -for filename in os.listdir("./"): - if fnmatch.fnmatch(filename, "*.png"): - print(filename) - os.system("pngquant --skip-if-larger --quality=8-32 --output ./%s.new ./%s" % (filename, filename)) - -print "\n>>> Copy" -for filename in os.listdir("./"): - if fnmatch.fnmatch(filename, "*.new"): - print(filename) - os.remove("./" + filename[:-4]) - os.rename("./" + filename, "./" + filename[:-4]) - diff --git a/signs_bot/textures/shrink.sh b/signs_bot/textures/shrink.sh new file mode 100755 index 0000000..36036c5 --- /dev/null +++ b/signs_bot/textures/shrink.sh @@ -0,0 +1,2 @@ +#!/bin/bash +pngquant --skip-if-larger --quality=80 --strip *.png --ext .png --force \ No newline at end of file diff --git a/signs_bot/textures/signs_bot_and1.png b/signs_bot/textures/signs_bot_and1.png index e6a95bea067c23a9a1c2d4f660e6b5dd6e0bedc1..aa47209b53fed5c9039aafaf189561ae8533ee70 100644 GIT binary patch delta 25 hcmaFKxSDZ-BR^Y!Pl&5~fsdOK+tN4F%qI3l0|0Ey2>Jj3 delta 87 zcmZ3@_>ysgqpxgcNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= k85p>QL70(Y)*K0-AX|V>h^tR#p_>xhf?1oZCI&B5i3Q4{;30dM9BM*si- delta 87 zcmZ3@_>ysgqpxgcNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= j85p>QL70(Y)*K0-AX|V>h^tR#p}qX+l6En%i2>07G?5n) diff --git a/signs_bot/textures/signs_bot_and3.png b/signs_bot/textures/signs_bot_and3.png index 5b96414f1604f730ca31b7b56aac4edcc9f7d116..27040ce5c115e83dddafc1992a6071f421e6df7d 100644 GIT binary patch delta 25 gcmaFKxSDZ-BR^Y!Pl&5~fzL%2mV$&^-V^(x0d5Hh{Qv*} delta 87 zcmZ3@_>ysgqpxgcNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= j85p>QL70(Y)*K0-AX|V>h^tR#;YAjfQnCN+69b|FG|U$) diff --git a/signs_bot/textures/signs_bot_and_inv.png b/signs_bot/textures/signs_bot_and_inv.png index 0f0d9a99c93b2ad103db41d04c7a25acaf768505..24dc1d256617b85aa5e9732f40777061e6f25a1b 100644 GIT binary patch delta 145 zcmV;C0B-+@0?Gl9L4OQTOjJcja7;!b28V43|IZ8}Qu>?#0004WQchCvb_(6zqwI0fdkB2hq@52~SHGkt_jBps^>;HH#^voQqNuOHxx5$}>wc6x=<115)%-*@5Dm1s;*b z3=G`DAk4@xYmNj^kSD+=#MLLWusxUK|9KuaCARHmDS1F~#*!evUiOpvYwDg`tjP{n*ZgBm{?lxDZT&CSv^DX6 zUx`lnD19p8tNf~GSL_yW4G;455VD`J%g*?$-CAtW>LTu+2l`HO=a zcK`1i7D7No=W9D>003Z6OjJckL_$$hP(W7pa&&QjfPRsakeZyC zqoty=wX(UpxWT-;y}!J{!@$VH!pF(R&d|-$)X~+~)7aYA;M&>Y+}hmU+uq>a-Q(rp z*($8>-O;P@$>K`Xzk2bNx7N&o->9!W$&R5;7cQ_*gNFbuR%*O7H% zNvK=bkn#V2xpP8jD?pX{w38slj^w+up$5>wFd7C`6_Lw@&)i#$n#MWTx&`eMaDiP2 z!Q%-r+BcrZERS_twQ-?=o}V;v8(sq$-nk zWKxw$Z^~p-X);4mxssVorO_Bjw`5KeM4C($!l)OSsbd4NvJX`Ef#!XP@k<`Zy%3zX8-^I diff --git a/signs_bot/textures/signs_bot_base_left.png b/signs_bot/textures/signs_bot_base_left.png index 91e0d774769fd81e2d0df8e05e8ee50cb21ab6bb..08b78f72d2dcd2192531e16240d960dcee84fa4e 100644 GIT binary patch delta 392 zcmV;30eAk41eODk7=Hu<0001iRAK-QL{2zPsS#;7CM5 z$H~Ud(9M~fn9|hIv$e8zcXdEk_M@euQBzR5a6r}o00ALML_t(2&y|s(PQ*YEhGz}6 z9ns<^^nVrBU@$xYl9}6bxf6u& zi`~p*|9`*CKnREkU@-H{90G*$s4V-we~t=pe=WMXljBNMen5i5@R9SeDh5F0kcJ~mEs?cd zqmm3`Rt|%h$$zWq%5pJEJj%g*9yuoBR1TsgbFn0vknLi|0$^uha4rv(BaMxW3#O5y zmPVcVV$Grc%dWW{IUrR_jhL@F>J;+YOU4Gr{Om6doyR{p#Jan$Io7fTH&yA m$BH5cZf;+G`Fz;Y+c#uZf2uZU3d;Zh002ovPDHLkU;%=hh`b;G delta 510 zcmV9D>003Z6OjJckL_$$hP(W7pa&&QjfPRsakeZyC zqoty=wX(UpxWT-;y}!J{!@$VH!pF(R&d|-$)X~+~)7aYA;M&>Y+}hmU+uq>a-Q(rp z*($8>-O;P@$>K`XzkGD$>1R5;7ElZ$SHFbqX+87oO) zJiH}K1GNADm$hS34H%lHX-7f<68UlDpkU%COu`sr3?X>$KHR(Pp(w1i#y&AC_&{gc zOxNYNMtI|=YJV}cF}?^X$2dv`?|u5^TpbW<=Un5Pu;86QRFNHq!8*9KmX;{(xM9JT zrtf=0m|KqAp1OHKI|-pVNzf*81b2;G-+X6o_uD+hAT8Dx4odcuBXD5{9*8bMYv?5_ zQA*C4yC-JQ8kAH(>Xf6zc-0!jgMbY_^_xAg8LT~kQg_Defq{AemQSrFd*Jj?4S;%B z0%i|#Kt1q*;ey%#$V+k5fF!w*wkmFI7GU6%6v0Kb1pV4i(Ti~s-t07*qoM6N<$g5S0C AeEGyF>ZuF3`Jed6jU@6 zl#^&L;7$5$a)1bFpj{ZnqNG{4LasoOVw))1KDXckdx+d2e}BeHq~H!T{_okQWof2~ z$ok4L^Rm$L@~;-!=Vgv6zb@~wo+zVX7>EXY@|CadzA5wGH-nvgj9@;{JwLKT;RBuL zXJiybA*tHDydc9GF+>sEIfsn>!>br`B&tI|(;;G|DDe8T?-gq)wE)|}HesdK&~U@D zIM+GQS8OgDEPsh8R`67@=|{yP5t~iTG@97a1!47oJm$ajy{Lz^#zc>|PHrB)9tq@}PmzEEr!p^+-S95kk9q=v@Mb)k9}l_hB*3k?bhdx{vJ{ ycyoq$$@q0X=eiG2CgkY#LHU{g>N?LK*I#nGgT(YZH4Se70000; delta 534 zcmV+x0_pvt1EU0x7=H)@0000)q>9D>003Z6OjJckL_$$hP(W7pa&&QjfPRsakeZyC zqoty=wX(UpxWT-;y}!J{!@$VH!pF(R&d|-$)X~+~)7aYA;M&>Y+}hmU+uq>a-Q(rp z*($8>-O;P@$>K`XzkBHdcF4FCWENl8ROR5;6(Q;Uv+AP}6GUQgPK z6?HjEq5l70-Y%d8YSP>oUx>_O7jz8w5O~4EIcKdkh8CLT8@f&@)vFzS1)e}kYd!L* zr%A4Q9LL*^UVkGDenSY6L|B}4?#@&{4t{V6QG|RI1p;DRE$o%=Fve!Yahe3orzmNF z#)Jx4O+O_KJQ5Hhl2zpOSOY1#J1-Mf;JH47cff*~W?@mk*(MT6S{S&YwF!8XHqqJy zTrIM(X%JN**~Gg|jSn`(XKfQ{&B7+Iu4}SsX_5DAGk**$TiOBsMPR|IB#DcCm77&; z<(3?Pw%okJmIHgXKwEAwNiH`N2t}C#ms@_?K;pW}fg3LVL6qLOG^ldm0Ge{AAod(& zLY2eJ$6F4?zJQTQO%4@~+Mb6~4*c-%wl|;JK5o1+2VM3fqzwzP!5S=Hk`Y(?~=@ z=IG_d!@@vT_R!MLv$e9v$;K(b7rX!f0cA-?;K+V}97M3Qam7MNrIuC_3w!UQoZZ}6_ei=qHfe5Epg zKVTt@g2618DMhT!)!PT`Fry4Z7v1o|EtE$Wlw~W#+FAgipg+;nbvI7eO~WdROE8wO zY#=U!EY(xfMt@GS2}#+=A_XBPSwsJ1k!X@7K6(p^Wg}4m5r|XRamX%_;rUIKa@;9lG!Zuu$F`=gAbD)1Mp)_dmng+&*r0#NaPh* zYdL=O5&l=Q0lRpCUI_ThVoaDv+aj$n@2EP=gVzvz$UGzg7~qM0?AH+HaR#0X7Z80I to(J#taoT>b0$!Q$=e&KT#`lro{V%qll<#KEf&u^l002ovPDHLkV1o8b+-?8> delta 589 zcmV-T09D>003Z6OjJckL_$$hP(W7pa&&QjfPRsakeZyC zqoty=wX(UpxWT-;y}!J{!@$VH!pF(R&d|-$)X~+~)7aYA;M&>Y+}hmU+uq>a-Q(rp z*($8>-O;P@$>K`XzkIafb@;Q#;ufJsC_R5;6pQ_+%xAPn5`NhpY5 zbtq!}|G&J1L|fatxwV!NLc;D6bOi6c^9Q081Z#N>^coXPd->Nh2K|$Ot=6@kSR0BC z959?~+a?i(kbg^gT1qQ!%VnY*c**lmaJ&=b7I68jYTjtA|l}envCN( z_7(%5fo3*r4P2)bXg(KV!~7_f19srKKet+dJEnQ!DpbO|jZO%x^njQ>_#-1Tlbp>> zN>GN1cbZU|(JM`$To3s{b3r>5geJaeM*KsQd0uHka(_B1VT2~I@4L{<^PRsN&51Io zcc`xd8FVUE!X7$M2rD5v6xM-wQHel0BsH5d96EqQ(CqdvyD7tAHx=L#?>dm(yy?Kq zteXx&b%-%xUU`pvk^i{pKmvT&Ekc|+aKJ@}i5{{0O@}JGnI0AnN-0dFLvw~K`tpJg zdE5u}Lq>D}i}Z0H{<`*~MK`Jrzh8T9J=Gz#71bf?eURpLm+p4fqwv+uhpL*V9NuLI3~& z|NsBc($A~crf&cM0Ov_WK~yNuZILmK!yphvCrD`9p>Q8z`2xYt1wtg3>tOm+Nt-G@ zfhCT;GlM}{E5AZt1ONR2V6UI$pI%>#ch)nD4LHKV09cX}b58fZ?8(a&M_SlWS*bzSA~nPV*+$RMb-hQe{&u2c>Jq58uRYW=|Vuh%(qAe9l0TA#>7 z&Rq&e6A|Lgo-r!Ng=(Z!_kqYyfGYdAL;Z#`8_VNEU%zs1?DYp6P=Pm9%WRDR0000< KMNUMnLSTZ&4V5tf delta 886 zcmV-+1Bv{{0)YpR7=H)`0001UdV2H#000JJOGiWi{{a60|De66lK=n!32;bRa{vGf z6951U69E94oEQKA00(qQO+^Re0~{0{Uiz^?#9F<#2obEw-6K;T;dWnkr2=iBjQoe!GG>SoMZ->bh@jmJ z%d)6_`%?7Mb^vf3Cz+E{0-#i<6?!a{@lTcN%#V*9C641H1#W&}5Nu-GzXM}CHgq>9 zGHfhWvU%Es5PyX^DTNt?Y1`ZkGGoW-EOA}e_-Fa`{Y)C7Q`mK6q}n~u;r!_{04%Mp zB>l4X=*6@0G)!9*g;Xj#vWwgb04wj`0Z@@Kkz-MjF&nW!2uT!$2q_VfV19ZA5eZzO z5U!0Y6ai{$763GxP3rYJzVCDU-dzA{wXXnpp2wM!r+@hD)u`3J^4Y85`#$x0oknAg z*@;P7trh^SR*OdaXVSLYZQAX2`4pJus?`yeR#y;0=5pH^FT8r0%wlTK*@?-*y7}puq_6R_6%7kYSpV)PG|Y#6X?4XQI5Lwer6g0AuJoki;e$u| zE1`*oc{*lj=u)6z#=$Nfd(qG}E0#=v_x#Ok0IpuRNDu^EK6|c|06koI%G}hoPGoHh z*LHD52_43Isb;P(vM@#eH z)c%nU=yI$9*DnnT|8woObs$}iH-e1KSeC_s{fGY9OGt;mX9V&K{_E3hXs=`6_lM@dFF(E$U|A9vGynhq M07*qoM6N<$g6g`UMF0Q* diff --git a/signs_bot/textures/signs_bot_bot_flap_top.png b/signs_bot/textures/signs_bot_bot_flap_top.png index dd5e82a0f890e84562314721ab200bfc72daa796..9ee556a56ae93c1ae53b4a7946dfc06b43bb1027 100644 GIT binary patch delta 9 QcmaFEc%5;A)5P$p02LAh6#xJL delta 27 gcmcc4_=a(UlVE{IWHAE+w=f7ZGR&GIG0|=&0BVK@AOHXW diff --git a/signs_bot/textures/signs_bot_changer1.png b/signs_bot/textures/signs_bot_changer1.png index 27da88b4ad93c823df0eac52178c18e9a6939f76..4fa6811157f1191404ac3727a62ebb8a3ba602de 100644 GIT binary patch delta 25 hcmcb}IGJ&RBR^Y!Pl&5~fscoa)7z9!QzrH~0|0Gi35);$ delta 87 zcmbQtc#&~}qpxgcNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= k85p>QL70(Y)*K0-AX|V>h^tR#p@)mp3!&>bCI&bI04Vbp@c;k- diff --git a/signs_bot/textures/signs_bot_changer2.png b/signs_bot/textures/signs_bot_changer2.png index 6c3633704f097bacfaa7760db0a9ff87cbcc8ef3..4b811c0a9099ba0377d49381e89bf3ad7b6d0138 100644 GIT binary patch delta 25 hcmcb~IGb^TBR^Y!Pl&5~fscoa)7z9!QzrI#0|0LB38Vl3 delta 87 zcmbQuc$0C0qpxgcNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= k85p>QL70(Y)*K0-AX|V>h^tR#p@)mp3!&>bCI)x|04`e?2><{9 diff --git a/signs_bot/textures/signs_bot_changer3.png b/signs_bot/textures/signs_bot_changer3.png index 7ea99fb52ca2063a469654eb7dd49d2db5002535..1b8e4f2b70eab4e37cacd764717fdec1ddd9bf59 100644 GIT binary patch delta 25 hcmcc4IFoULBR^Y!Pl&5~fscoa)7z9!QzrI#0swA|37!A| delta 87 zcmbQqc%5;AqpxgcNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= k85p>QL70(Y)*K0-AX|V>h^tR#p@)mp3!&>bCI)x{04)I+0{{R3 diff --git a/signs_bot/textures/signs_bot_changer4.png b/signs_bot/textures/signs_bot_changer4.png index f21cd0242ebaeb0076e4c0f4a746db8ab3ed8d39..06754f88a55f471927a086cd6e73f3b83e19992c 100644 GIT binary patch delta 25 hcmcc0IGu5VBR^Y!Pl&5~fscoa)7z9!QzrJg0|0I+377x? delta 87 zcmbQvc$IO2qpxgcNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= k85p>QL70(Y)*K0-AX|V>h^tR#p@)mp3!&>bCI+|z04t{#{Qv*} diff --git a/signs_bot/textures/signs_bot_chest_front.png b/signs_bot/textures/signs_bot_chest_front.png index 512cd8f19deb87ac08c15a732c2395efe8598f3d..30a6f520b46249259a68df04e20981623bd78692 100644 GIT binary patch delta 292 zcmV+<0o(qJ1Ka|TL4O`lOjJeS;@_K{n&|51)z{PS@a?y`w!*`}MMp$HR`!B}fgXa4kUc&AY2K%gQ3!PW+CxjE9w>j{hTcQD%*vDYcIt>x;BLSqty$%fIXU9Ae8M qf8_Z13`vgcYaNdL>wA}qCoC_fp-K?}(@#(U0000Bw}?cLwp z=<4UUxwgW?z@MR?nw*)In3hFHL_k*df`fsZj*LS9008buL_t(2&%IF13W7io9uT~b zE8Pw8oJa=UEa_ZC_qGl`K%f*ofW1LN#~|<(_5n)hp_*AODt`((^&Mu|-I?!aK`A?C zAYu>%N`acaKtUG>1{V|NCXB)3`GKoOo<+cZwW7$Kf4#lCU)`aX_6xEew%ksz!{jzLilb&Q3;VNxp zlhcy<%uU+JCQYXW%eFQtqLxjv1m7h+>-YEq#kctA)7x+Hh4>Jk md_@27@s@U*Kd{g9-Q@;ZFJ$#qbN^+Pl&5~flqrb$N%#@9xhJDW`(m%oYDXQtDg&; delta 93 zcmcb{IE86~W3X&yNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= q85p>QL70(Y)*K0-AWwi#h^tR#VS6se|MNT^E>8dVF`Stg)&Ky>kQ)5} diff --git a/signs_bot/textures/signs_bot_delayer.png b/signs_bot/textures/signs_bot_delayer.png index 0e689fa5e15b595806be32df62eac6ed39eacdfe..3a43d91c78e63dc3f4dd5b2e4caf5e0b62d61475 100644 GIT binary patch delta 28 kcmaFBxQKCrqY!6+Pl&5~fe!-%!}_&r7~1SsPMqiu0D#&Fj{pDw delta 90 zcmZ3)_<(VOV}NXCNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= l85p>QL70(Y)*K0tV1Q4Et50Sjkhy;C8jZ<*&n5=@0|0dh7^DCI diff --git a/signs_bot/textures/signs_bot_delayer_inv.png b/signs_bot/textures/signs_bot_delayer_inv.png index cb4241e9cdf95f2ef267b960ea296cad06777f45..2985dc19c86808d561646a6ed923a89bd34d3b16 100644 GIT binary patch delta 131 zcmey(xR-H)V-0_RPl&5~flqrb2Ll7c|MNWS*RGj!&r=@AVJr#q3ubV5b|VeQvG;Uw z4AD5BoUnj5L8OJ5v7^CICLq{>lVt*H$efsvIX%4wEK@GBP6=S`nKEU{NA84-gGm~4 j?H3RIe$nVt%fOKPUh{Hp_^mlWqZmA0{an^LB{Ts5$YU>+ delta 169 zcmdnX_?vNpW0-7aNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= z85p>QL70(Y)*K0-Ab)^Qh^tR#;s5hI?YSI4f%R+Ge0SxTFfmfbBdCd)wWC2nCLs8L z1j__gpEC6DRru0Dx!-Pyhe` delta 90 zcmZ3)_<(VOV}NXCNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= k85p>QL70(Y)*K0tV1Q4Et50Sjkol&Med(iux{1O50Cjp8qW}N^ diff --git a/signs_bot/textures/signs_bot_delayer_on.png b/signs_bot/textures/signs_bot_delayer_on.png index 756982e886ff3d11f253d583325cbe885bd36fb5..1dabb6a4b46864fb51baafa79bf9d447af973d75 100644 GIT binary patch delta 28 kcmaFBxQKCrqY!6+Pl&5~fe!-%!$lUBpNip~6DRru0DEf)?EnA( delta 90 zcmZ3)_<(VOV}NXCNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= k85p>QL70(Y)*K0tV1Q4Et50Sjka>}X<)VrDv5CR{0BlVccmMzZ diff --git a/signs_bot/textures/signs_bot_doc_image.png b/signs_bot/textures/signs_bot_doc_image.png index a5f4a39dd680ce2343da520d939375a8f1a288ea..7554980e0c1bd0a2a63a676dcc5edc6bd2b9e295 100644 GIT binary patch literal 8454 zcmV+hA^F~kP)d}BqDlO0-FU&W$W+}`qxt=DLh#FV$;b)3wkrJJXk zevgE3czYHiL}5fSCUnTb8h_OJ_w?1@WykP%_{uc^^g zOz3-Tf%4?@E`L8mVsJrA-CIFZzcCt&tkuils7l;##1kqdD9^q_&Q!VoU0uV74|*9Db4 zGX4~+2gWRxX%W*D+mwRHTv9*uPSNS2s4#v@Ovs3w1&68RmE^R4iZPAx0fhpqnvw*tM}8+-oN~^O6(mE-lwprDu{xjq$!UI zpO52Rgw68JlvlmJzK#paGKKKj$d%AEwWsGt)Ti;Y)Ct3m?MPv$8)_$nS6i9p16<(s z@y7#qyCAs#kuHXhXsVBihm}K&96nB~R7B8e2%Q7ymzNhV$*`ehS>`gl;GE0P-&+-Q zKOt_R+1?$HUE1vich?!A;5dO}XEd4Yj(a9_I`m1Q1!<^IXTh-#V|pL@ z{_*>B9vsMUgr1&XUcSG6e;vF=s-_BQx~}NDbfC@VICRAng^8_^q9}CSKUJ*GPH`^^GJ3HX~K;-pcEs_1C9jd-}wu!1^;i0j&(%zkF2hdxEYOO@I zQsWF&kk^ORLk_rMaFhWjt<4VJ$<~6-N^YU3AQv`D*Rgx=#!Ax1;G$ahenh3~A40Og_U=Os1Gr#4WTH z;VpsO3K$@!k0j##_%rI|d8^G<`_v{uFBSngZD&#_B@?TLEQFY@3HseUeeVUFYJ(mp zI-=^qRN_Jg#57m|hyf$iJ*$CVWg;P&tR90NeEy+co_E+GKr<`M`2?ZW>DP&X1~Guf z-a@0uq0<2+ot(Hacn+j#Dj7{W=8~oB=x59=6#_vwsK_KKDa&mLTc}z9J*+C)8(mb@ z&!9iQY@wBK#BRgMWWmX4D}5^TWMbC!3O1;DHKWBAIK8|2bj{+ z_t8RwotY$MRvx>pGL)NJD#Qm?kH`0_J_gOgNs@Iokt-9l9QPuHoL&JntG!ii6#xK> zfc=Xr4iyb8aa}`^WIYEYnK#ges!Ld+Gj7CY66Xnrs;%e>w%RbwO%c|T_3-fU_^@}t z$IVZmpVXbxlROQ3Jpnz*-K!`O(15+FwRH{5r3!WWVNX#2NvJCZ*qCG8lVUejL@GJ~ zw-g=YH;&^hOs1W7N;0+S)J_vqZ4&X}y*>!d2>R-(aT=h#>2w0Tt2J<|>Uv&_cCdrK zLukxHC3lgU5qzA8#%%;LRS(k&G8dukEHgx<)?HUg6AQYr#uTpIz1IUlzkJZ?tF6<$ zWRZ+ktN9#upk_#pV*3}50&IWW!B9=0@F9GR2?_7z+}0)Reql<`8r)ZCfxEWkx>A~` z7%Y&8N1(@ddrrTI{pFa`CO~%pS|X2gj>|fZYFd&q=q)@*-E=DErXY7zCS#(jiJMu|DVs_vHW(2i zZ6a!tJw6oOgRcrQ3ERmNwU@2ghtOZJyO=b3SPDI%&Herya1k0cXYF-Sk-@1E>Pf8N zz^NFSPF+S+4~^=y>9|cI;v_65pg6{oN6{v!Tin5pJZgu~UH?|7P(3|8N!yaAg(JR5 zxMPZeshOMlv;GQpU|pf*E%Z)~L8U@T;%4~BjHZuss2(;YV(7TBlE-P5idqfCX)-lz z8cm_Oj0c19cEbnk(ZPs8o7PUYyFb~TX39GlPFJ)39H8g(<$OMy&)~RZWJz=FvExu5 zmx4?Zb5hn$s5~$L8V3z<+Ldz`m@{agF#JieZCa`r<`vG`%k7W{htNNidTb5Q=`WYd z?rb(+{<#EXfS&c)puIGH20&x^kd3S{IBU8%4AcOP;h|bkR5W^rJV zWja>}M>PIz=uvq2Cop%HOLV%socEXg85{3iJK{3V|IkV@Su9^NqmdIp0LZvr0chx# z2G8RrKrlYyX`Tht#%;XNjkw-TdxB1jm5rutgXGuH5GUcPJ6kSiU^T#YyYuDja@J*g z%r^tW5Gw$lLQEreCe|%bKCpUl{7f4vp_GfEBZZ|ThsZFeP|_0%jF;5GO{)Pt#3@`H ze+^LdNKxO$@_T4ptA{4ELIj@m`#?Io1n};%-|x;Y8D4nMTzp_qAJ-K*#pH$p66Z25 zxDYzf6a(#1Av}_4Ea`T$dci$Cmq-xv=4G63O0PD?V39%6aU1IM-{=;8u8j`3F) zh+&8i2osj(+@(&=6@l5XUSAJx#zi^mOunM<$i5v>uXla@1byeKhl>6p)cl(o#g;I9 zK%fc|klzz3gygPCL@ySF3$^B&A@k2}Ql`8bts1}oH@R>3fv7X;JsHW4y2+FGboY6? zneJC_Np~_#7eiei>Lx=&d_gK){n=ffsSBV+yoe*N(*(^y4W<3i3xP?{bzMxFwkyrSpdA+)N4#fDHm~VURTWru@Q1~3EZ?Kn3QvUqv@!uo*?e0PU2hd0V znEFsLA+@Dj8(kb1QyeB6k9#8xiGFucMibXN~ z?kzlebvnT7+$L17YQ5et@VkC|i41 zR(tGW6#5||>-zRc|KrCs4F)fdTS0%oizKHOpZ(3n&>SkdLN#QlEAOG7WfyMyRqoR} z+3-s_+!9w0F|jGnIqBO%)cH7MV>b~UG-Z=5Br-wM_1X1hX@JxmaNYb0&I~QZ&Xje6+h$gbo%ozP`-xqx6VDe2<2(49o$16!=)TM;D4^ zZb)ZSw@h7hy2!_K7Rwnzl}F?~VD4W_UKH3NPh_YUFM>L|q*uq;*v>j=t{ztmyX>xy z_OEltkOz+RyLKe!KoTDk1yuDXMO$hdX!0Ab6%oT>-E zW|oU_6v%-cx)ng@Zd0O+;2f`I^&k*d`iv;{=7T;rl;%@hLU$8Le+;GNEDO+KP35kt+ANR!u!hn_$%%;bPOh@tZ}sh$ z&?4;5LxOkRaCG^h(;JzVZs@wEnyNLlbg_K99+4olvZ5sB%&lrK<5N6iXwgk|0qvvQ zMUniwm{1}X62|+QQ&Q*uL2sY#A0GVf9JjsjcV@ala56Rx!_f#@w=Bzi2YvpS z#Z;n1iLNz5h4mP^>$jo+^-4Ol&?};Vhj&nY0_RsZd0|(ai2Fl=_`_CeDgyCq=*iP} zT2D_;A3|T>UXS8RT%Y`H=_bO%vQ*@urU^QUmb|4fG87&J4HMU(d_?4pq|RAG&^9L! zx^A}+sCBYzL#Ci^;?}N0g4Rui9RoHL*k3`1_xBPS*x|3x06r0IJ)h4bK%1s9FjUht z5hDXboOdC}*pISF^m}MLx3;_`(3Exd@dRDX}>L)ms}1* zW6xA@Ylu1QA3-mBYJ>;MrI!&b6=;U`I1veYZ2LU;VCYaP?MF?CZfjP;%hEAohpM5Q z8nzQlHJneO!>|kI@2oUIyKX?xaXssZ@2cudLK~_^TC2zu1IIW=bibA!+?|i+sUYZ> z#x=Fq4?aBMx!iOhJW!{DFwU#4;R174x?GVura6Eh295#!^YGYiJLc~!^$t<(+GBzy z;G0?9zJRzsUCr(5%fEF6!J#Vn!ZxDhoxfRt=BWpr7*&~j2$Ld{HLn45Y@(#FwX>=ii%17%~Y+$1h@fx06as@ZIhZ`hZ4oMDy8QJw3(#RaIR~r?U~D zQRsBdL?fUfSBAepv-v<1khgSp6t#rzl%Ci=w{|`aR>54mbb?KSERJZD!M4Kl6C*)j zpxUJa=Zl!$O6czr9?*gB5%g_7ufLs6&v;Z{)zfbU`k8+$a?;#=p)?^8-$C=>1AmZG zZbPw(_-Gq>FVsWHXd{F`&cn%^0y; z^eG~b0;t@>c(Blkil;O&KZmaByCXCr`tT4QV|u-Y#_P@I8?yanCSzLPsMNC{pi!vB zInN*3cE5%Aie@AS0&nO>24m;)flQ=3Mf~p^yu7(?wJiqznxNw12o7jLENrW73D84VvZh8Aut zi3OEwgmA+Vu|;KDapKWe!iy9q!9O`%LaB3;9}WZ^O+pDhg3{&9OH0r=S+LeKhDIXl zgMmfkF;g81KDo&9!Lh#@fU_&kSzv^40!fp_imnJb zHQ`#v=(wsMDIEqCt31Dfy^VHmJj}8}4 z+(G8~U6up(VYi!fH(l%=I@;6Vt*+YDbX^^xHD{mz8sV`K2HcYYBZ&wBIJ8b22ldr) zARZJn)MPzv3B1jHui=!V5MDS4;>AjmLQ>AZlw`M*)EV&kLLdA$XmmL@931s1kjAP1 zNz_5l)~8Uqddc?FZ&f`%LaQ(!Lv7#yntV0fhyh~;{3J2(cCZdWr&>E$ELM(+2ybBo z%C@42!1vSCB#l=Kk~CSQ_|P02C>Lt#ten&&FFhFirnDdCSw%Y6zSr05{%5_?H|uHr zvu$6>>a;qW0s4|+dWfTNcwy-(T1BA@6$82s@HhCIf#W2|eF(>I4I`hfP+Ah`I$iG% z2WZD7LS`GjNNJ=nDi7*UlH$|iQ&M2z^1nW8fhB3lcAU^c`3J795*F&N1kV_g`ss*MD67!c-=v_y6AB|NY|~%o>pI z&vk|j5Y6dAeHFi2SdqED>Cs>;5b@T;^xUQ$FW5;&!5j3ryqw^wZ zEk~fwufFo;=EMEn#V_t09hlxB{O>hy-CpSa+&{m;*g81|Tx~Y1v;ZP3`mlwxvXFIw z!vjz`8Ld!8mbeS7JU&TJ)})ND3+e*wW8Y|?M@Ih-V8JD5gJzZc1W ze7^khDQ+bK-?t7FLd3YLo{5jGh3ug2iKJZyty?IYPq@*cZPrPYl1Hp4JOWqGKa0#o zFZ*_pu?!x2yacV5a(nmdH1g)`H9&vB-0?ujZ(n_R6~p;o{Ad_;J;*Zps=?>b@_?aV zwxW}2A-CYH*X|QB)dJAPY1!Pv$_a9b7_;nomcn<+?vY{mF!e{EzpANRT>TpK$r5)BS~s_ zKrqv*RST%U#Fe2`U`!fA8-Bp|lQ)MuhE(+R-N|o$E$_mhUjy>zch7G%UtazN-{^S1 z1(cB9Dre98S%v4+K(xTWpvsHy2@j)E;pERb0%4cRxuI8xq;ep^Sd zPQTtioL&8HD9{PQr;CqoKYV${GEaa1kr9f9&VmNeNxvzk{&ELT6~xK^v1GHf;-*`<55{Jgdp3Alw=bR<$2?{CAo zY(Po%xrjXC!2<9K)xk`yX*p}*^L4KA+D?@S$3X;qBxqibKR)wU(FFYH_mE#Q{T%YU z^B?1UJ`(nPTTJAGE1FExFD{Ox;WCKYL#PQ{}T zo@0?wepjnSs;Y`W=Z3q{QZs!S)R4GPNC)iJSovmC(@+3^A#QItFCtz&PM~!_cYpg{ z_gY>82h(Q<(1yGoSF0zcjeflbax@pzms_voOcpixvI(P{Xk1bND~oDrGVu-E2)wD` zt2H@f$6Kx!OINOX6lOBLS_NnUzq>tq^E2?%laNP1UYp*zV2>*^z2=2H4He6CXA&w# zt_>y6Op;`TG+)k@(Cdc2gU4Kx<)c5^k4{?R5>(?n7lW>Mz`h+p+4kZ3`Sr)w&!;bd zpT4<#f{fY&%#ln3^T>xQ;U?9U++-*-I)+(=wZSG5-5Ukh45GDYtRW^z27=BdwusMi zH7)yz#~?LE+A45A0`qoUZMWn8829zZyFZ^8zcA=aL*_DfE2%=_5a=B)JOt>5GYmlH zWS{bwTcl;hAkXNH7}s}Avg@@;#Xv!IX>v*pZfu8^klH1gMqQ#J$N5X(U|hiA;{Y9y zsS7|9Xfqz5w>z<3VT9?51j~;CD2xU*FCOItyd0TIQYgabcQ9n|K`-ayY^jAO?FnsF zccW^B#T}GQQ(3Jaeq#K+ejolMSSCuMo6-|yMr=Zi65{b`0U%5i0;n_hMg|n$;!f-Jp(0M5le*yAZrvI`0J)RYewkSi_R1VKcA#QbrWo8Tuk%vx~dgB*w~0ztV<<_*fH>iAXiZ6gY^_jN+d2f`Rq}1 zx{6e#dbWbJj>2H28M^OpXt{d=f7lcETD^quCzm65naGZixjud+)9Z=`&`PD*JLyIA z?0&8&=~7;%W6C6Z2ye6LSzbzD_)GW`)uZ1jVLEfVmOM}|wY$M$I|?*ZJ?D3G>Eyt4 z)M6Co^c10^Bf1y%DnBKp+B%>}j5z#)AFF?nsjDW{VPxIe)?o*18YcqjDn;P3x%546 zPj#uMvbugX?oon14e%z8g(A1>XLy=w_d_1t)XOX2!l?~L~V^+~g6MqD`A>6WIDKu2L- zc^wf+4fYw+{1Lsgd_?LEFobXDq&O8lomiEY0_6Q;s%6Sy$YLbWa!$OQ=N+P_) z57M4H0;S>!%YTa=1yv%by#>XfRS}&nZptE!r?}Relc60t-io!Lu?AsXJ<$eCQQQvLIjU-Xx421KZkNv1G3QsXJ>SQuO-%v=>4DF5CrdDDR$-`&s!@}pSHP?rs*v3D7 odJfcVKDH7y0vVADOOr|SKcm>?`nM1s0ssI207*qoM6N<$f{B7**8l(j literal 33396 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 diff --git a/signs_bot/textures/signs_bot_extender_inv.png b/signs_bot/textures/signs_bot_extender_inv.png index 8342103294abf7c91fffd1d9ca123e670cf1a473..1789880b55d351611263a9535e8d5ffcfeadf301 100644 GIT binary patch delta 108 zcmaFNxQuavV=7O8Pl&5~fzL%2miAnZ|L1vB6xL5>U|?V@3GxeOaCmkj4am{75e(3#KMJF5))?lv{W0^I!Z7w>`BU>=)!2!1k}dh M>FVdQ&MBb@05&`)4FCWD delta 170 zcmZ3+_?U5mW4&xQL70(Y)*K0-AWwi#h^tR#VS6se|MNT-Sy+;GX#f>4FqQ=Q1v5B2yO9RuXnDFg zhDcmaPEcTLX<{@|&Jq>SQ9TeLB_-8*O!>$E`BpqUlRFFem+5mbGn@_a->9HxeiEpS N!PC{xWt~$(69C*YFnIs~ diff --git a/signs_bot/textures/signs_bot_extender_on.png b/signs_bot/textures/signs_bot_extender_on.png index 4a6b7bb88fcee79639d5643627dac0a4f6247b38..cf281729f48eaa87e9005f74c232f55da2ef8bc9 100644 GIT binary patch delta 92 zcmcb}IE`_FV<=~UPl#)KF311#JQrD5E_-|FGcYh{d%8G=NL)_lXk}uPGGLOBh&b4D w;6gySNgK2Bl!sd<7%;DsI4rY6)Z`N@L*kC0+}yH=dZ0E2Pgg&ebxsLQ0D+YriU0rr delta 152 zcmbQnc#&~}W4&xQL70(Y)*K0tV1Q4E>;LmS?YSHmSy-Muw&n#2YIwRhhDcmaPFSFrz{|_aU>qSK v!E!-jkzzpG6`?~sJCb;cAB0`tU|?9E$|g9`=y0VXP!ofvtDnm{r-UW|wqPqj diff --git a/signs_bot/textures/signs_bot_extender_side.png b/signs_bot/textures/signs_bot_extender_side.png index 1209248595a5204b54240215b95e9e3bd407ad2e..d58a3546b4abb3cf715f820f32e2509142c5d762 100644 GIT binary patch delta 8 PcmdnZSUbUSV!aIj50(R0 delta 68 zcmb>3%{al)S~fEzqQp5rH#aq}gaHJci&7IyQd1PlGfOfQ+&z5*QuI>Uf#RG69+AZi R4BWyX%*Zfnj>JSedjPN}5ySuh diff --git a/signs_bot/textures/signs_bot_form_level_bg.png b/signs_bot/textures/signs_bot_form_level_bg.png index 57465836457d6851f0dc7f28f4bdc802d55c9865..f5c1dccb727f108fb2481790a6321bcde3d01800 100644 GIT binary patch delta 36 scmcb>IEitBo0NNjPgGP?V#necf1_70FfcHd1o;IsI6S+NHgTR20QN}@w*UYD delta 98 zcmbQlc!6<(TZB($VN_I9V#neQFSMUCFfcHd1o;IsI6S+N2IRIEitBo0NNjPh!X7?p6C=-ko-ufq{XsB*-tA!Qt7Bw2AYK02R*gTe~DWM4fvFsAB delta 168 zcmYe?$v8oxo`a2nfkFQB|3o0gmgMd3!tfsi7wla=87RV8;1OBOz`!jG!i)^F=12eq z*-JcqUD+QqGYaa6v&j7v2MWn%hD4M&=jZ08=9K`s3=Gaisfi`2DGKG8B^e6tp1uJo zda3Lng`O^sAr_~TQxXz5QWr27C>aKDxbaGuCR}Man8d&^SDK-;VPWWUkP)7)elF{r G5}E*(!!0ua diff --git a/signs_bot/textures/signs_bot_missing_node.png b/signs_bot/textures/signs_bot_missing_node.png index 674f3673dcaa5b2bf2ccf130107109c9bff5d040..edb442a0430521456349e0ded98d47172cb012b3 100644 GIT binary patch delta 260 zcmeyzw3lguW4%y-Pl)S(B*4hX$iTqBQn&OXkYX(f@(Ye>FP`;BO=LkhP+*6ri(`n! z`PzvWc@Hb_xah8yJFtPlLRdlUVf)|kmy#TdCeG^i`EYq6gL|p>Rrgg}MP!XOTQsmq zd$}ltcpu2=lznm6SSwtsk#A;DVe=WUBeh<${Ma29+}rK(d6Hejjuj`__4~{V+CTfa zo!;PRB_pdar(ST^J;rG<{k?mezVW|#EbmY?`+N+Odvq0p#f(QU5AZTgVSHwO!{T4e zCihY%GiRRC`FwvFvb-I2wVN*GFwSc1*T_HGv9FGC`(!OHCy)P{Ku<7uy85}Sb4q9e E0F6X#!2kdN delta 326 zcmdnX^p9zRV?AeqM`SSr1Gg{;GcwGYBf-GHAR6Ek;`$#IFfuX%Wo}*$U;q|-o0C`ae~n- zUWGNu#wU2z?QrHZJZtGJ@w(-uK$yXyaE^4lya-vgkOi6M6=GKk>|}*m%g%rKqy8Y( z;eT`Qo&)#uWq)vdKT*L@ztHsrugl4Ya~@ZD@K~rxS#M$tx8!|N!8|*l`Pl>e`#(<3 zl1+*Cy0%K@Nav1soj7ikG*56w1W!kU)6<=v#_b+VS#gjna OGI+ZBxvXHcQEr1k3kdpDj6c4Ej_^L?MDPIr2j~zpL_c1T(j{N7Wh$PQa!Cp6dOok~ eGw$beeXPI888Wq>IXg%I0000_CX>@2HM@dakSAh-}00009 za7bBm000XU000XU0RWnu7ytkO7*I@9MYFiOtFW}Zz{I4ft;^5TnxCVJj*)nJd}mU(WDtUaV={n3H|S0i zT{c;|0igj8*t%9QqeWOn!FI5>!~h;USWp3Woi-j77VaQ~Mx&A|6?9F6yeeb^f&PPQ z#x^T(U4e?HjsBe z`Df(oFKFWApF_K@wVZhcY=^%pzySY&4Dbf|)1Uw;y(`9-7k6|>2ltv1_WkQ?-|u$s c_x-m20YyGWlx^EfG5`Po07*qoM6N<$g8gc^8~^|S diff --git a/signs_bot/textures/signs_bot_robot_back.png b/signs_bot/textures/signs_bot_robot_back.png index 97459b3d499332deabaad45a30df25e73b2c97c4..78916f22368f37c7d59f623c81868714b71d99b8 100644 GIT binary patch delta 172 zcmZo<-orRSqMn7Bfq|hhB>gy$5)JSPaeeyqsgcD7An*VG|ISs@uV26Z>C-3a@{CtN zp(IZi#}JM4$p&U=W^K&O$;oU#w#XtUCoNUGY|U@p22Kna#?3-f2Lu=x Yj{J_Vy)Erp0kn?6)78&qol`;+02FyZx&QzG delta 370 zcmV-&0ge8=0f7UM7=H)`0001UdV2H#000JJOGiWiLI5KGBSRcHod5s;32;bRa{vGf z6951U69E94oEQKA00(qQO+^Rd2M7@~07e4dW&i*H8FWQhbVF}#ZDnqB07G(RVRU6= zAa`kWXdp*PO;A^X4i^9b0O?6YK~z}7?UXSN!Y~X)Kd6g`tbbm5f$mJ4f-5j`5zfFl zkQmvS*t=I%C9fGghRIb`3ZfDrAmYVp2LIQe?;wn-X_^qLre-gZxRL`bLI`1auv#CZ z3SKXp?{XjmAg^I+fMR^GJ)EKnp7*;P!W_a3@O%v)RbAJ!23J+}UH||n%Mz*zW`_43 z&bhlj7q*yd8EX;2dk+A87ZCt}s)C5(WxzQHRh|4MA~5r3LTFZt2$;DSHb!zT(ZP9qQp5rH#aq}gu%HeHL)Z$MWH;iBtya7(>EZzkx!g~fq}EYBeIx* Rfm;}a85w5Hk(lVK0sxOF5uN}5 diff --git a/signs_bot/textures/signs_bot_robot_front.png b/signs_bot/textures/signs_bot_robot_front.png index 330e62c2591f095bf1750913864b16bcd905316e..e53fbf4404aedc9fcc5e4c1f67eea0528ef0fa65 100644 GIT binary patch delta 288 zcmV+*0pI?a1+W5;8Gi!+002a!ipBr{07y_wR7C*-0D5CeXlPh!N=D?~-9#ZFK|(-5 zdYAqG{NUo=tzA)_nQ)huh(>rpnwCIML}EfhqyNo7j%#0PO^89EPq;vJw2e~6*1V5n zV8H+Y0HaAnK~y-)y^;$K!XOMlDb+G7|4qIBO$C+2VE2iOzJCO0;E_^54TaMn@|aee zg=6Kp(85l5wYRVrjA?=~UkPhx*k9(NU}o4Z9A@}u6*W>Fp8_#>wAuki1QLW8HK48p z@?H=!pBtK45ZpvW*OZ_P)(V2X5g`B|5;-Rbz-23iPWFU8GbZ8()Nlj2>E@cM* z00Iw5L_t(Y$7B5a{|^HUJbwI0R#uLIGJs|X69bI_3oZ$FC4W_9?#_F+NmW3=0%SdC zW)ZJ|fCUT;3@+8P85kIt@yhOLO~qrvz{LT?31$|O4Epo;56MM^ zgM&jHC*K{hzkl+kUoUK7Gc_|k`Qq+9ftRK)x!%A0ed9;02FGGSan@rGzaBVnfSe#= zWJq58J@hR*@9it>3=9k>U)*J2U{LxX{+6BhpPUdc)Bfu}e#x7DjSL~Xuv0vs$MNx* zo(uzn1cN??v?0Uk^AfUG|Bzpr?iIba-RwW(ls6D=v46Lax5GOI28Ob^>}PKLgb3b= z^JidSV3@v!91DCk{ERhps~K7t7#K7;*p6TMdHf1D0|Ud?m%lYR*slNh#lXO@`Nk&l zeemMoo{y)GLfF@T{9<_ci;qc(fq~)Ezk6^sk(YTH7#MbwXMw!wR}b^AFY5Rfe-G8* zekw0^dw-|luRtCno(GZ=uWvrqe)IQVO}xSk44cTYVEGz`3tQM27=G|F?Z5u@ zp5Q-jmM7n?e)!G6z##nd`>!kPY~Md$=DK+O>n}2c=m2W+K0w`^j4Njjy0VDAg&oVE m|CHA`Xo1ei$TY-*2mtUl!zUSxh|&N6002ovP6b4+LSTYir7O<> diff --git a/signs_bot/textures/signs_bot_robot_left.png b/signs_bot/textures/signs_bot_robot_left.png index 46ccd2e5901b98f55fd53ffc0ed82402070e331b..5185501863e2d57fb002399161a76f15346932d9 100644 GIT binary patch delta 203 zcmV;+05t#n0^0$Q7=Hu<0001iRA003g$Uf(zyUiJV0002ovPDHLk FV1j5hNXGyG delta 365 zcmcc3_=jnNL_G&H0|SH0lCEPwDj~op#FdeWfsaLji77^%i%p%!IiJBWf}7V|o?BH_ zoXv#MP@UaHQ87QL70(Y z)*K0-AbW|YuPgf_b`BvPvpI>Lu|Ofo64!_l=ltB<)VvY~=c3falGGH1^30M91$R&1 zfbd2>aiF4FPZ!4!i_=Fh-Q{Xf;9*U8UuN2**L2nK{(oKW&Z1{-`%CnmFVEXBVVcj% znQ1Y6>zme{<9~44kX`xt!Hg$vlO04h9xUS77@yD;I7h$Z>sRFtr?|-s9XDAgtw9?iV*}p;7tU>r-WOSx8i=KdUvm?TjkhdMluKvZCZ4(Lby9vC&?O9>u6{1- HoD!MyUxU}V1e@Bcp!9^HF#@2+Fj^e^AEV{Ao^ zol-KF=l=C8D*3A|J5X_+r;B5V#`)xcAfuor=2TTxwj>sog$^A|j7DpCU72pM#!O(S zbG~|MQUL3vu+)VdD^gQa7jSG@x^*E}M#++eTr0wtm@ee7of4k1AYygg$}25O0d|~M t6CGGrFeR{hFbP1h@kchrCF0TL_G&H0|SH0lCEPwDj~op#FdeWfsaLji77^%i%p%!IiJBWf}7V|o?BH_ zoXv#MP@UaHQ87QL70(Y z)*K0-AbW|YuPgf_b`Bw4R;yK#TtFeo64!_l=ltB<)VvY~=c3falGGH1^30M91$R&1 zfbd2>aiF4dPZ!4!i_=FZZR9$jz~i#pvbD)sG55m%|EJ|EZzkx!g~fq}EYBeIx* Rfm;}a85w5Hk(d~u0RWR<5w-vT diff --git a/signs_bot/textures/signs_bot_sensor1.png b/signs_bot/textures/signs_bot_sensor1.png index 4eaa5f3fb9c8eb2757321f5cfecf587a94a90c5f..628319f4cdb88e3d8a137a68195d7d36fe4ff98d 100644 GIT binary patch delta 127 zcmey)xRY^$V+DVJPl&5~fzL%2miAnZ|L1wunz33Lf7!vnz`$4%X=1m(X8p<$OE@qm-?a&l<^ypDesS^h>99A?O f|!S3j3^P6ZrW0-7aNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= z85p>QL70(Y)*K0-Ab)^Qh^tR#;YAjf|L1wyb2-+Uu}0p@m7EwU?P}J>%*-Z`AlAZc z#M*O_p?Tt@O+qpZmW!FDa62?zJ96}>q|}K684fENj&VyeX`Eza2*2aFPA2VRD99C_ Lu6{1-oD!MggeV}NXCNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= m85p>QL70(Y)*K0tV1Q4Et50TOdoIWS^E^otOJ7V34gdgyu^H9? diff --git a/signs_bot/textures/signs_bot_sensor3.png b/signs_bot/textures/signs_bot_sensor3.png index 210d3ef5cb3177a68c6113cfccab3a986d137e8a..1f5242caaa9472db1335e9031644a31a1d4211b9 100644 GIT binary patch delta 175 zcmV;g08sy?0_XvdL4OZWOjJcja7@tz1cz-1|IZAqHU&B}^tb>300DGTPE!Ct=GbNc z003%9L_t(2&tqUv?wYrE>6%u21WzI9ng3o dLjWZ?005_ZPmlWHl+6GD002ovPDHLkV1n^XIxPSI delta 213 zcmaFCxQuCnW0-7aNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= z85p>QL70(Y)*K0-Ab)^Qh^tR#;YAjf|L1wyb2-+Uu}0p@m7EwUU1HY8%*-Z`AlAZc z#M*O_p?Tt@O%sJg7$Q$8Fs9CE5DanPT*Y#vfx}^{#6eaCuLC9_4w8!)6dBA*8(0lw z+TNA$oL^WiuiOyOEFiQ+O;7LK1qU`a=0maQL70(Y)*K0-AX|V>h^tR#p@)mp3!&>bCI%z|06jSvO8@`> diff --git a/signs_bot/textures/signs_bot_sensor_bot_inv.png b/signs_bot/textures/signs_bot_sensor_bot_inv.png index df4b6c9d5d8f66bc441ba49ef8c1f236f1c4cedc..bb6601f586037b7224e9c46acb59154891b77176 100644 GIT binary patch delta 31 ncmbQqbenO4qbN^+Pl&5~fscoaQ+qDQ|MNUP0XHKiPH6=Ir|Jv6 delta 93 zcmcc3IFo6DW3X&yNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= q85p>QL70(Y)*K0-AWwi#h^tR#p@)l8doIWS^E{;`eG?{zwE_Ue(;A8Z diff --git a/signs_bot/textures/signs_bot_sensor_bot_on.png b/signs_bot/textures/signs_bot_sensor_bot_on.png index de94a897f473085c24c21aacaf04559a338ee051..316a13ab8f97b90465fb3c2d8cf96f59380c869f 100644 GIT binary patch delta 25 gcmaFQxRG&!BR^Y!Pl&5~fzL%2mV$&^-V^&00dFq}4*&oF delta 87 zcmdnU_?~fsqpxgcNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= j85p>QL70(Y)*K0-AX|V>h^tR#;YAjfQnCN+69W~1{_>+5sXSPQe3PCy2lnSR9MgCIfvWHb*xBg=8~BB1)X|b8}PkN`PDj2Ir#G#FEq$h4Rdj3Kt6CHJwt*` zqQ|OXVi;#%#DPNx4jc%W*fPt(>e=6e0*gfwj5jCWn}5;dK!f?5>hD(qk4{ROzD!Yy zsk-c4LP6p8gd3ZS*(2Kye-Yc=Bj&Q0PonfdfG%h39ovA6qSH)lZNbhvRF?R~IxJ(} zRzBY+>4T2xVS&T!9-;O-7B@)92dt{gF!Q?V_wT4y-RU_qOV}U0nssqeVAtAgvnUb% hdpS1@-}A@HFfgorVK*&ZPVfiFv!1SgF6*2UngEDre`o*z diff --git a/signs_bot/textures/signs_bot_sensor_cart_inv.png b/signs_bot/textures/signs_bot_sensor_cart_inv.png index f6494783d6c53221ab6ef3323992952dc99b77da..50250fa357bd7e04557cccf6a6ea14beba680113 100644 GIT binary patch delta 34 qcmeyxxQB6qqXd6|Pl&5~fscoaQ%`qSdoIWS^E}U&ERUNwJsAMsXbwpL delta 96 zcmdnP_=|CZW0-7aNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= t85p>QL70(Y)*K0-Ab)^Qh^tR#p@)l8Pj^>)F311#JR2YS-<=ql3;;MK9SQ&d diff --git a/signs_bot/textures/signs_bot_sensor_cart_on.png b/signs_bot/textures/signs_bot_sensor_cart_on.png index fabc6e169174ddb20e6ed34a617d81f96224628f..74d71240c02ddd63457f2ef78438b914f9ce455e 100644 GIT binary patch delta 178 zcmaFCbck_+L_G^L0|P^2NcwRgB^uxp;_6=DbCHFmr@QO_d7k!M4i6WnwPvgzuc&7M z6)=_r`2{mLJiCzw{$Fy5SeZ~jG-0}bYLs=r?eJUS_9`Z7f+ zrs}eH2?d4U6AIR@Q9AwM?%P}*kcdW^q;7|stih{>g;7Ggc2pnuY`l{p>DWre7@?r$ zdO-@88E^0QH>{X8E3xAt^O9BacLE)H_%%Z9O{AA*ssB$B-Jg2SXBTrp>Di2n8b`00 mO6zv9=bOEm@x5J-kAY!knSJ;B2r(;=mpxtmT-G@yGywoz)Psxw diff --git a/signs_bot/textures/signs_bot_sensor_crop.png b/signs_bot/textures/signs_bot_sensor_crop.png index 7f5e87d6162238d80a666d694bbe40e063c2fc70..a67e1067dca8760d76b3ceb545dd966c02907c20 100644 GIT binary patch delta 28 kcmeyyxPx(mqY!6+Pl&5~flp>;riY8u%u79m6DOtu0FUkp%>V!Z delta 90 zcmdnN_>FObV}NXCNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= m85p>QL70(Y)*K0tV1Q4Et50TOW@e^`i_^yAf9xg(rvd472x)0)|IZ9aL_*m&jk%GRBVWR&6Ce}F{yViq zgIEt<><4nRohpB$IxtdKncm{tHRfB_1C3g|!v90094kSGUudr_O>TiAf&THFQW kVWN3IOdlKI`{ez30CaLFa)b(0Z2$lO07*qoM6N<$f;3<=XaE2J delta 192 zcmcc3IFo6DW0-7aNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= z85p>QL70(Y)*K0-Ab)^Qh^tR#VS6se|MNVVnVB9gPP;#P&zl&j9N%QXxL^3f-}0FObV}NXCNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= m85p>QL70(Y)*K0tV1Q4Et50U(LKl}FU7hvM;^s^YP6Ysspc#w+ diff --git a/signs_bot/textures/signs_bot_sensor_node.png b/signs_bot/textures/signs_bot_sensor_node.png index 7c8f0962a9f10e5b96e4d2f44003e2e8209bf787..11d0d7746fc4c8160080f29702d6b99867509c8a 100644 GIT binary patch delta 103 zcmeBVI?Xu2QG!3fC&bmgz{kVIY2t(lVPRq0w{A`SI7M~hbUhbEmsX{i0}?7qD_T?- zLe1P#nW7VT^>aA7$4_K*Uj$bC*}t%X111130hT$E;DXs;7;sB{*c!vF-Hu6{1- HoD!M^voQqNuOHxx5$}>wc6x=<115)%-*@5Dm1s;*b z3=G`DAk4@xYmNj^kUzjD#MLLW(8I+kEG%r|gbCZXZavyj(mgR!&qc|lRWZhaQ$;DG zM}`~f0LTZ6zy!d2kO)jb7@|T5Az%zLLr4ipz*rE-M-eav z@@Xs}2oX>eLHGqEpeTauTVo+b5!CPyL=6wj5QBgK?14;u0078EHrbZCtnvT=002ov JPDHLkV1hB_H+KL4 delta 217 zcmaFMxSDB#V~lKONJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= z85p>QL70(Y)*K0-plE^voQqNuOHxx5$}>wc6x=<115)%-*@5Dm1s;*b z3=G`DAk4@xYmNj^kUzjD#MLLW(8I-PqNU~5*w{10#h2S7YbHj@gtVfcTZ2S~1vxN8oim`j5Ef*F`E z?QBzd3gm`)x;TbtoKF^TVdiP}ZD8a%z@+EVAgJ;nhlky*DT7H(fKgbS2Z+VfOGHmF zC0u>MBw$;>D4e{&Ojv|*ftU$nauDkQJLgg*_DPo~?&TLta9}d&Vq=JRv14fc)EEb} Og2B_(&t;ucLK6TN%`P|q delta 310 zcmdnVc$8^^L_G%^0|P^GRn-?D#g^pl?!xdN1Q+aGJ{c&&S>O>_%)r1c48n{Iv*t(u z1=&kHeO=ifGmD9e8VUuNtpWMX8A;sVNHOnI#zt?w-B@ zDSD~wK=GBHE{-7)hu=;&f^q%kz*|GSjGJDPRNmqt*c8CN_gL_ zk#Z2f605kZ^@4S(PQ$DV@*(03y0>?KX|(xdlFt|yVfcTZ2S~1vxN8oim`j5Ef*F`E z?QBzd3gkw5x;TbtoKF^TVdiP}ZD8a%z@+EVAgJ;nhlkxQLG+xOo&lrqjE2tcZsRV7 z3B5WDNlsG~I33P73OQU(Vk%?V)W9hctkjUVLe=m>q{8%>2^I1>2O3y1M0go4AF}IP Tx1dD=XbXdO>_%)r1c48n{Iv*t(u z1=&kHeO=ifbMOgUaCG-yn+Ft<%?ybsan8@pP0cF-av2z$i&7IyQd1PlGfOfQ+&z5* zQuI>Uf#N$oT^vIq4!@ml%hh1O(<)s5_C=_SP0#W#27GZx121X@c&{?^)%DUD zQ&qK&$BeomF}xvhYzYi(0kQ|4<{2oy(LCSYd)`nwPgQxIz=ie%S&L`uIxP5Je|q8Y zp~);{ekiluglWm1408f_yjUOT8O6^yr|Q@7+d)Ik*EvjC>Eih;g=zWkeno4jcS^O} zn?_A2x!-oNe!1dP^Q8(`WghISwOV3(@TtqfhfM4Zt(WU0k7w*pV+)Xez+$(^>43ra R4XZ)^^K|udS?83{1ON_6ca#7C diff --git a/signs_bot/textures/signs_bot_sign_aspen.png b/signs_bot/textures/signs_bot_sign_aspen.png new file mode 100644 index 0000000000000000000000000000000000000000..63b4ece30d52167ee531a00a5709de2c09104144 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4*UKki}RM(*X(2238){hYk{o3QIb)6qYPm(h=_v z;K>=ggeW4&xQL70(Y)*K0-AWwi#h->J72A|AAAn*Tqp0m-bs(~z~k|4ieHU@>0S^I!Ibx#+^ z5Q)pl2@6;`czIbTtv+y|u`%&~y~2;VfcTZ2S~1vxN8oim`j5Ef*F`E z?QBzd3gm`(x;TbtoIiWfk?Vj0kITg`9C1sH&1c;C@3U3&h6cwjjW6pT-Ilm`YQkS$ z9j*^o3Y#xjoo1NRB)nvQK!1@3?<*IlGY!5Em}kW+?B0;c|MMr~v|lfz^)eROF=Xu( RV+2~j;OXk;vd$@?2>>}`KbQaj delta 328 zcmdnac%5m2L_G%^0|P^GRn-?D#g^pl?!xdN1Q+aGJ{c&&S>O>_%)r1c48n{Iv*t(u z1=&kHeO=ifGYgBDDCy+>m;@A(%?ybsan8@pP0cF-av2z$i&7IyQd1PlGfOfQ+&z5* zQuI>Uf#SP8T^vIq4!@o5%h#g7q}$vyBz}{pQREs<_V0x#MwA=Hmk&vzAl3^Mt;}uVGnqvQh4`QuxMG znU2MsSHs_hls;(K!PKd)e4Rg5S;k+kf4;|!r_~GGcFkjui23}*s_oA#&I36Ovfsnp TW^8Lw1$)uc)z4*}Q$iB}jM;p~ diff --git a/signs_bot/textures/signs_bot_sign_copy3x3x3.png b/signs_bot/textures/signs_bot_sign_copy3x3x3.png index d5d064d2c94186c323f93723734b054335f394d3..26db90ca67e7bc6cc5fa85fe2a3717ee7619ddf5 100644 GIT binary patch delta 176 zcmcb|bbxV!L_G^L0|P^2NcwRg#UJ1k;u`v&!M(r-$OD2$HWB`hqzr&8=8_=4U}lC( z6W*Sz2XbRQT^vI+&YztS$kkxL<6O;R>s`z=`S<*j76sbPFZ<=&HcdS)bj|HgY;|z< z=8WA8S4xkt>|lC%%_85y(XOVnySpqQ!omKeAeUyxm0OQY8lD6nd+o0ta9n@2Ciky6 Y^|pxyVtO0)z5}_z)78&qol`;+0FZe>Z~y=R delta 335 zcmX@Wc#mmO>_%)r1c48n{Iv*t(u z1=&kHeO=ifv#^TkDQugO903%P%?ybsan8@pP0cF-av2z$i&7IyQd1PlGfOfQ+&z5* zQuI>Uf#QceT^vIq4!;e%$azG8$9G-*xrc1q8?!}Z0tMUpbg;JNejZ z2Y=~;a<+TtXEVvlym*jzw2Sk_0|hDWi#O({#jNRa(Cdj=Q^l{sx-v5;ynCbZgw2z> zV?Aay?OvnL_i+E_sGg~fi(5lv#TU1hm{zqceW=w|`CCl)KVzuWzIiMgKF$s{Yx$%p c%Ct9|J;^=$(W`Y2`#~P{boFyt=akR{08-?EKmY&$ diff --git a/signs_bot/textures/signs_bot_sign_farming.png b/signs_bot/textures/signs_bot_sign_farming.png index 28a2e5b536b26056654fa49ee973cbccd9969605..8e8e61b2227325ae45b8bf9775db16f10ef11879 100644 GIT binary patch delta 9 Qcmeyzcz|(&XadqcvxNM`SSr1Gg{;GcwGYBf-GHAe$KyQR1ARo12`> diff --git a/signs_bot/textures/signs_bot_sign_flowers.png b/signs_bot/textures/signs_bot_sign_flowers.png index 992c0baf472aeead6c8a4b9beff937dbc6529e7f..d53fb5e56e1fefe7488bb410588a3abdb1ea5848 100644 GIT binary patch delta 187 zcmey$beeI3L_G^L0|P^2NcwRgB^2Nj;_6=D6Z#*>VfcTZ2S_dv6qIZK{}sq$E(!7r zW?;UwvrXkGkell1;uxZF{_MrGybT5%tO+s;S9ACTm@B;5-{lbed6hc9+CFD#yG#40 z+|vDGzQF4s<4qx}_?x#`O25xYaSD6IAU0Lo=?kxkVz`0cMHA-@H`o+^pWax>AKj4J llb_%scV1uNg!}yhrt_y9eAs?QF9q7j;OXk;vd$@?2>^}^M7IC{ delta 358 zcmX@j_?2mbL_G%^0|P^GRn-?D#g^pl?!xdN1Q+aGJ{c&&S>O>_%)r1c48n{Iv*t(u z1=&kHeO=j~FiQ(at8lEk>If8)%?ybsan8@pP0cF-av2z$i&7IyQd1PlGfOfQ+&z5* zQuI>Uf#NqkT^vIq4!@nYSF}Ze=eThF(RX1xn?&y%JoR(Ujf0{(d7@Td3$OmPkP~E_ zsFvCK=O5=!0d{8HkS%Ol(%cD*Itz9&OnmL2_{Q-0-Gk~jeA_1pYO`!{tuRiQ7A|Pv z^_Mg4L6>i>d!6+2uWw#i?_`Tv!Ef^QZlRun%3AJYm9{ds4Wb`}7F-h!P)d4uQSyWB z;duV6ZY`yTu5;`?CtZr&*_XJ@4`~t6*vfHHmWL~mn^#Hel7P(8wu67f>%znrT)8=U z^7X=NR{N4OIaftwr7>_D-@a`2WPXs?hb^^?XA1(09z3q$2KnF9)z4*}Q$iB}Ikkn$ diff --git a/signs_bot/textures/signs_bot_sign_left.png b/signs_bot/textures/signs_bot_sign_left.png index a1c9309615a29f22c6ceb35d14cadad5fbea0293..6bb3637918ba6e23290f27a93526e25a057ab56c 100644 GIT binary patch delta 141 zcmZo*I>tD`v7RTuC&bmgz$f%S0}%W_&-1P%cMXumR1)MD%)mDPLk2I9=jG|*7$R{w znWL47Ez3wkLZYE3G(q8%z^?!H0)Mz&)BfD%PyN$m7{`3|9kbyz=Bo`7zrQUueh|cQ qwBT(4v*DX23+59E49u7IFf%w@Xi?MM&8P{o&eN66&t;ucLK6U-jxs6$ delta 199 zcmX@c*uXTwv0gSaB%;JQKQ}iuuY>^voQqNuOHxx5$}>wc6x=<115)%-*@5Dm1s;*b z3=G`DAk4@xYmNj^kSD+=#5MFkgHL85koW&Q&)Miz)j$?gNswPK8-v2htbIV9o2QFo zh{WaOgaxb|yu7TFRv$Rf*qHdgUg5`ahlVphw#%RT!J52>ZPi`&q&4iT7!AL@bx%LA rRG{nOt%qz$H&_eVj)V%dPh?=Y{4KPB>ASrj&`1VPS3j3^P6Mj!5V| z;0a<>@#zpZC}VU=VJs;Z5OXNE+Vp*56Psqk3Ne0${8t9d|C~O(1X<|m>gTe~DWM4f D(~U3y delta 319 zcmZ3>c#dg;L_G%^0|P^GRn-?D#g^pl?!xdN1Q+aGJ{c&&S>O>_%)r1c48n{Iv*t(u z1=&kHeO=ifv#^TknVWh)n-3I{%?ybsan8@pP0cF-av2z$i&7IyQd1PlGfOfQ+&z5* zQuI>Uf#RDyT^vIq4kz>cJ%8YgK|@1*XJW&_70hn32Co_z%Ne+rvaLx=`QhDF^`)tw zwY#xClO)gy3RVL*bPx=iRbw6x^EgNlJwdM++@x-w>@gSbQ9BgKenFanA=KSr$64b&8$llPboFyt I=akR{0Bo~$FaQ7m diff --git a/signs_bot/textures/signs_bot_sign_right.png b/signs_bot/textures/signs_bot_sign_right.png index ba4200053df391387f694a1c07d3b1a7ad13cd51..b99975167bbbfccdf8766d32dd4c12402e4e3bfb 100644 GIT binary patch delta 140 zcmZo*I?6b~v7RTuC&bmgz$f%S0}%W_&-1P%cMXumR1)MD%)rU-UpfcK^YnCa43W5; z%+bokmSrR%A<@tinxJq>VAp?pfj``?sef+sC$C{Q{KhzSADeN5SKUF0|KAoG*Dcg& p%XT*tIIGuT+`z+Tpm5fj!QyF~9Ov(yKS8#6y85xYtaD0e0s!KLFnRz0 delta 199 zcmX@g*uXTwv0gSaB%;JQKQ}iuuY>^voQqNuOHxx5$}>wc6x=<115)%-*@5Dm1s;*b z3=G`DAk4@xYmNj^kSD+=#5MFkgHL85koW&Q&)Miz)j$?gNswPKC&TikF!fK9;lH=e>3^I8 pd9L^6D9nl#NOy=~EtKG7U^v4aUQrhAKNn~ugQu&X%Q~loCIClxKjHuY diff --git a/signs_bot/textures/signs_bot_sign_soup.png b/signs_bot/textures/signs_bot_sign_soup.png new file mode 100644 index 0000000000000000000000000000000000000000..b60f960e107e5faff7234ee2824f8523389f5ead GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4S0D`p^$ZOElNkP==b4jt zT_4D2ED7=pW^j0RBMr!L@pN$v(Kw%+AmQX7z}dj+67%4|#2Q9Xj_aIy3sQL4yb2iA zI~us093+pJJ8|rAV408;*d);?P!Pn#B+3=j^|028fx+~p`ptmVfcTZ2S~1vxN8oim`j5Ef*F`E z?QBzd3gm`(x;TbtoKF^TVdiP}ZD8a%z@+EVAgJ;nhlky*DT7HZfKfbMScFlbzoB6x zx5wnoo!l`8Bvzcb$O>_%)r1c48n{Iv*t(u z1=&kHeO=ifGmD5Ci@LYWyaE)G%?ybsan8@pP0cF-av2z$i&7IyQd1PlGfOfQ+&z5* zQuI>Uf#SP8T^vIq4!;d|6SY*;5}&*-dEDy)^&$lArT}a*ZZ5#WsB4n|Z%@W<}o?zqLOK z#2u%c@mw_TxyQyVhNVXCwBnkLr+&fmvv4FO#mcUfrJ16 diff --git a/signs_bot/textures/signs_bot_sign_take.png b/signs_bot/textures/signs_bot_sign_take.png index 25515cc7eb0af3d841d74a4b7963b5ec3067f2ad..b50010055f380a2d9bad89df2dedc646e455be3d 100644 GIT binary patch delta 168 zcmX@iw1aViL_G^L0|P^2NcwRg#UJ1k;_6=D6Z#*>VfcTZ2S~1vxN8oim`j5Ef*F`E z?QBzd3gm`*x;TbtoKF^TVdiP}ZD8a%z@+EVAgJ;nhlky*$$(L~qk+@qz>%XjSbc%y zQOQ`=O$;}9Oc;|*7=3XD>&%nWHa>=>-07S9IS Oz~JfX=d#Wzp$PyZgffr- delta 308 zcmdnNc$jH|L_G%^0|P^GRn-?D#g^pl?!xdN1Q+aGJ{c&&S>O>_%)r1c48n{Iv*t(u z1=&kHeO=ifGmD9eDnESb{s<@}n;8;O;+&tGo0?Yw<%t%b+_B&y3AXi*RvbLJM2L<1%CRLqEnn|2Lm?@A1UU z6S{uRSEmOkE%_t9`w7#64bPPOF78WXTfkeuIOn!5hs*iwZ6M!xy85}Sb4q9e05cJF A1poj5 diff --git a/signs_bot/textures/signs_bot_sign_take_cart.png b/signs_bot/textures/signs_bot_sign_take_cart.png index 2ebf93d52ac2da03d940f1a846282507ad2d76a8..5f339c8c30330e31aa81e82e2d6a0d602f99a887 100644 GIT binary patch delta 169 zcmcb@w3BgyL_G^L0|P^2NcwRg#UJ1k;_6=D6Z#*>VfcTZ2S~1vxN8oim`j5Ef*F`E z?QBzd3gm`)x;TbtoIiUpkgLIfhxtNPOYG5SY^VR8Uvj!+$`8$^#=kaho|z`ze|Vh) zH>5~kC{E2cPhe7O@MNBFw?5 delta 325 zcmdnVc!g<#L_G%^0|P^GRn-?D#g^pl?!xdN1Q+aGJ{c&&S>O>_%)r1c48n{Iv*t(u z1=&kHeO=ifbMOgUNL83EzXlYN%?ybsan8@pP0cF-av2z$i&7IyQd1PlGfOfQ+&z5* zQuI>Uf#N$nT^vIq4!@ml%hzDQ(dt+)xwosi{o@q5WzFG*SFWt&G~@Z(Xrfl4()OKk zz3L;m#J0xtrh~^BWeza5F$d%~F+W`S)2{x9het(pSdD^0yMVR8;UuNL+ojKBXGjTe zHChuY_rPhTw(O(7YEK>s&G~8i#K}-cD{f(squgZ~=gFL=`J9c{=r}R(4^W!?cDPapQvT`!?9{(44{Kft>J_D%-tkQp-xF+8g Qj{VAp?pfj``;Q$PNa7g%U;!ifD5k3usekH=>|hOKWqH45J8 QNP>*@boFyt=akR{0CXcIp8x;= delta 176 zcmZ3-_>ysgV?AeqM`SSr1Gg{;GcwGYBf-GHAe$KyQR1ARo12|IhQBjb2p^WHFTl`2}+@?DKLr0P^%b zT^vIsE+;1}VCCTDWu3J8z=6ib#Q*gQKaOiUXg&UFui%t8A(iilq(Hc%j2jaJgQrqd UQ~f^8mq5J?p00i_>zopr0QWpJRR910 diff --git a/signs_bot/textures/signs_bot_sign_water.png b/signs_bot/textures/signs_bot_sign_water.png new file mode 100644 index 0000000000000000000000000000000000000000..272ef34e044ee3ad9a4560ff221d4decec5c446a GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4S0D`r|9yOX{-5U&(r;4$ z@)=8l{DK)Ap4~_Ta$G%K978nDCnrcaIS6nzu)4%NI3T#Z!MG#6NoN5I%MaF`DO09Q zWQ}oP(p$nQp{*&on8Tu3*HO&C%$N7)p}V17npNSV6XVy85}Sb4q9e E0A3<14FCWD literal 0 HcmV?d00001 diff --git a/signs_bot/textures/signs_bot_timer.png b/signs_bot/textures/signs_bot_timer.png index d02f6ddbd926568856df29e0927ff61bccc39927..c22f113c88cf37e406e2a024fe843dd70874b7ad 100644 GIT binary patch delta 25 hcmey*c#v^|BR^Y!Pl&5~fscoa)7z9!QzrHm0swY23KjqW delta 87 zcmX@e_@8ltqpxgcNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= k85p>QL70(Y)*K0-AX|V>h^tR#p@)mp3!&>bCI%D&07wZKdjJ3c diff --git a/signs_bot/textures/signs_bot_timer_inv.png b/signs_bot/textures/signs_bot_timer_inv.png index f659cfa8d1325e25ccf690c14e8a296c7208c3cd..3a4df54d190bdd943b7e639fd42d4d974cbaa870 100644 GIT binary patch delta 31 ncmZ3+^n!7MqbN^+Pl&5~fscoaQ+qDQ|MNUP0XHKiPMHJ%s{;$< delta 93 zcmaFCxQuCnW3X&yNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= q85p>QL70(Y)*K0-AWwi#h^tR#p@)l8doIWS^E{;`eG?{zO#%SVI2y44 diff --git a/signs_bot/textures/signs_bot_timer_on.png b/signs_bot/textures/signs_bot_timer_on.png index 646f1dfab9714d43b424e04bf8a316e23c617a42..cb72aa5f29f88cd1042d1c659398cd7e823cd281 100644 GIT binary patch delta 25 gcmey*c#v^|BR^Y!Pl&5~fzL%2mV$&^-V^%@0dhYHKL7v# delta 87 zcmX@e_@8ltqpxgcNJNQqer|4RUI_yTI2WZRmZYXAlxLP?D7bt22BhevvIE6A3p^r= j85p>QL70(Y)*K0-AX|V>h^tR#;YAjfQnCN+69WnXL#h{U diff --git a/signs_bot/textures/signs_bot_tool.png b/signs_bot/textures/signs_bot_tool.png index ce08e3c19247b2680d2207b9ab11c38433efc485..77de7b156f8c28de284822cc31b927c9d8a2ae1d 100644 GIT binary patch delta 376 zcmV-;0f+va1l0qOK?pfeOjJcja7>YhDS!6n&I$YIO8xe`v2X)`W5d?~000VfQchC< zb$kbiuzl0#|jA5-E+Llfb4}^`9 zx(%WeCPb3<-}$wW;O|so=xV$^<%G3P!bvy@C*e;BJNER9JLFZ*6U5Zgc_CX>@2HM@dakWG-a~ z00009a7bBm000XU000XU0RWnu7ytkOJWxzjMNDaNkx40k{pQXI`{+vj_PhT3-m!24 zOz~~J0000AbW%=J0Cj%FrNhtsT0V+vEK~z}7?Ud_wgdhxrSCN~tCFuLV zYXf3e?Un>Rd$y-_emkF&32?jpF?Fpp4rOH99k46uR+4S)-#7Mzs7j$QIG9BlQ4vCc z0kIOy6v_5~qebilhM%EZJg~v=3E3V-RB(?Bu?J3*P5Ru8A4zT-L2?H$VfK$JK#HK4 z0T#d67b%$y%mak|Di|%~6<~tkzU?yB(6T0oUy3IJdIsx7L9qn_ptUFx-VVTWD1a{m zz`Pn@DFC&`hKK;vLFzO?An$@M@1db@V;R7BQHl|6CeD*uYN5X~2v+}ymYXrB6UaA|#_1D7XLs002ovPDHLkV1gPrzPkVb diff --git a/signs_bot/textures/signs_bot_torch_animated.png b/signs_bot/textures/signs_bot_torch_animated.png index 3b5055be663febe24bad40a7d8988c0eb1837c99..89f14fb0ad6706fc783daadf9ca202efe94d6410 100644 GIT binary patch delta 490 zcmV*D3lgxbZAf>jXe=e_UVn%tK` z-mY5X)2!mmnrJx$=BgZrW*e$=9=WfL+Rh*ob z#!+8I00001bW%=J06^y0W&i*IDoI2^R9M5^m)nklFcd{AD6O{{pg@HYMI05K`Ty^m z2jhe5WMblzp1zc>G$dzdpG%GTXJuaiRSHn70h$%S;uB!`ar;W<(ReZ&x%qWZjC0mb zZEU0K?rs{F#>Q2z@Y~S1qC`$pd29Iy{aBFfcT*vhOrz60N(<1H9$#! zEZU#>qmROKku7fQND zB4ke4Lny^O$I_L6aU#n2i{}gg;n6LZsLq6%FF)k4_jyQ-A50FXHto g-Y={$xq^K81ID%@p2E5T8vpZm+oJK@p6}zD?c0^$)s)}FiQ>zE=h1xN!g=P$aL}e*;Za)ZO zGXUu9+vDTZ;MCLj`O(wT&)νL*PH@Vw&KyW7pX@8r3=-gnllUsIY zTbqJez>rm%Z%AxsMeoHz)}KM1bvBD~G{l@S=B+5_u_A(7BFl3hbyXfkF&?IO9cMut z-Ha2IWD|y54CI~) zL;#2d9Y_EG010qNS#tmY3ljhU3ljkVnw%H_000McNliruxf$gg^+NyL|D08KW)YYJfY zUXUI<7X^T|1iL@lvVSw)%{_2_)CT$3LkbZH$9$#?Z VG=f~@?`Z%4002ovPDHLkV1g2TrgH!Q diff --git a/signs_bot/textures/signs_bot_torch_bottom.png b/signs_bot/textures/signs_bot_torch_bottom.png index 84b72704901c466fc7fa95d0087db375db55b175..a1ef8537d3d46e49360fe63b54fedac9407fcb31 100644 GIT binary patch delta 111 zcmdnPIEQh91SbQnZZx!4Y^}PQ)plXS>V+&<8he-+UN`ah1w06M2P$Up MboFyt=akR{0JAJ6zW@LL delta 143 zcmbQkxQB6q1SbnK0|Ud`yN`kxM{l`xhB z`2{mLJiCzwvL>4nJa0`PlBg3pY5bP0l+XkK)8#5P diff --git a/signs_bot/textures/signs_bot_torch_top.png b/signs_bot/textures/signs_bot_torch_top.png index 15fd6372be8e3a5c7e6f9b80bae85fc10d8c08a5..fc242788ff99cbb25dbfb00343bd074506729cde 100644 GIT binary patch delta 116 zcmX@XxS4T+TdsS7kAad%l8a`bg_5qk(48~09_=qmar6&oU|?V@3GxeOaCmkj4am{= zba4#fxSpH<1cnI>3~sDEZH$b9%Bsp&6;zc|*~A?kHwrj93SQcxY<%Dx14A%B%lbfl Rw+BG244$rjF6*2UngA+3BAEaH delta 138 zcmdnYc!F_)TfI+ap{~48l8a`bg_41i$elB@9_=q$T2aja1dJs?e!&b5&u*jvIh+L^ zk;M!Q+`=Ht$S`Y;1W-`l)5S4_<9c!e5SS!1Fo?18v@tRYDyu4ARZvwDvhjg)3=FffSPvX1$^dC)@O1TaS;y>@&;$U?$tJe| diff --git a/techage/basis/laser_lib.lua b/techage/basis/laser_lib.lua index 802b3c3..9df03cb 100644 --- a/techage/basis/laser_lib.lua +++ b/techage/basis/laser_lib.lua @@ -102,7 +102,7 @@ for _, size in ipairs(SIZES) do physical = false, collide_with_objects = false, pointable = false, - static_save = false, + static_save = true, visual_size = {x = size, y = 0.05, z = 0.05}, glow = 14, shaded = true, diff --git a/techage/energy_storage/heatexchanger2.lua b/techage/energy_storage/heatexchanger2.lua index 1cb7c9f..967e26a 100644 --- a/techage/energy_storage/heatexchanger2.lua +++ b/techage/energy_storage/heatexchanger2.lua @@ -130,6 +130,9 @@ end local function check_TES_integrity(pos, nvm) nvm.ticks = (nvm.ticks or 0) + 1 + if (nvm.ticks % 5) == 0 then -- every 10 saec + glowing(pos, nvm, (nvm.capa or 0) / (nvm.capa_max or 1) > 0.8) + end if (nvm.ticks % 30) == 0 then -- every minute return heatexchanger1_cmnd(pos, "volume") end diff --git a/techage/logic/logic_block.lua b/techage/logic/logic_block.lua index d81d463..4f91d0c 100644 --- a/techage/logic/logic_block.lua +++ b/techage/logic/logic_block.lua @@ -87,8 +87,19 @@ local function check_num(pos, num, player_name) end end +local function debug(mem, text) + mem.debug = mem.debug or {} + if #mem.debug > 20 then + table.remove(mem.debug, 1) + end + local s = string.format("%.3f", techage.SystemTime) .. " s: " .. text + table.insert(mem.debug, s) +end + local function send(pos, num, val) local nvm = techage.get_nvm(pos) + local mem = techage.get_mem(pos) + debug(mem, "(outp) " .. num .. " = " .. val) if num == "me" then nvm.outp_tbl = nvm.outp_tbl or {} @@ -242,7 +253,7 @@ local function formspec(pos, meta) local inputs, outputs = data(nvm) local bt = nvm.blocking_time or 1 return "size[10,8.2]" .. - "tabheader[0,0;tab;"..S("Rules") .. "," .. S("Help")..";1;;true]" .. + "tabheader[0,0;tab;"..S("Rules") .. "," .. S("Help") .. "," .. S("Debug") .. ";1;;true]" .. "container[0.4,0.1]" .. rules(meta) .. "container_end[]" .. @@ -263,10 +274,20 @@ end local function formspec_help() return "size[10,8.2]" .. - "tabheader[0,0;tab;"..S("Rules") .. "," .. S("Help")..";2;;true]" .. + "tabheader[0,0;tab;"..S("Rules") .. "," .. S("Help") .. "," .. S("Debug") .. ";2;;true]" .. "textarea[0.3,0.3;9.9,8.5;;;"..minetest.formspec_escape(HELP).."]" end +local function formspec_debug(mem) + mem.debug = mem.debug or {} + local s = table.concat(mem.debug, "\n") + return "size[10,8.2]" .. + "tabheader[0,0;tab;"..S("Rules") .. "," .. S("Help") .. "," .. S("Debug") .. ";3;;true]" .. + "textarea[0.3,0.3;9.9,8.5;;;"..minetest.formspec_escape(s).."]" .. + "button[1.5,7.5;3,1;update2;" .. S("Update") .. "]" .. + "button[5.6,7.5;3,1;clear;" .. S("Clear") .. "]" +end + minetest.register_node("techage:ta3_logic2", { description = S("TA3 Logic Block"), tiles = { @@ -302,10 +323,20 @@ minetest.register_node("techage:ta3_logic2", { nvm.blocking_time = tonumber(fields.bt) or 0.1 nvm.inp_tbl = {me = "off"} nvm.outp_tbl = {} + elseif fields.update2 then + local mem = techage.get_mem(pos) + meta:set_string("formspec", formspec_debug(mem)) + elseif fields.clear then + local mem = techage.get_mem(pos) + mem.debug = {} + meta:set_string("formspec", formspec_debug(mem)) end if fields.tab == "2" then meta:set_string("formspec", formspec_help()) + elseif fields.tab == "3" then + local mem = techage.get_mem(pos) + meta:set_string("formspec", formspec_debug(mem)) else local nvm = techage.get_nvm(pos) local mem = techage.get_mem(pos) @@ -361,10 +392,13 @@ techage.register_node({"techage:ta3_logic2"}, { if src ~= nvm.own_num then if topic == "on" then + debug(mem, "(inp) " .. src .. " = on") nvm.inp_tbl[src] = "on" elseif topic == "off" then + debug(mem, "(inp) " .. src .. " = off") nvm.inp_tbl[src] = "off" else + debug(mem, "(inp) invalid command") return "unsupported" end diff --git a/techage/logic/programmer.lua b/techage/logic/programmer.lua index 5384989..efe2b09 100644 --- a/techage/logic/programmer.lua +++ b/techage/logic/programmer.lua @@ -25,7 +25,7 @@ local function join_to_string(tbl) end local function reset_programmer(itemstack, user, pointed_thing) - user:set_attribute("techage_prog_numbers", nil) + user:get_meta():set_string("techage_prog_numbers", nil) minetest.chat_send_player(user:get_player_name(), S("[TechAge Programmer] programmer reset")) return itemstack end @@ -35,9 +35,9 @@ local function read_number(itemstack, user, pointed_thing) if pos then local number = techage.get_node_number(pos) if number then - local numbers = minetest.deserialize(user:get_attribute("techage_prog_numbers")) or {} + local numbers = minetest.deserialize(user:get_meta():get_string("techage_prog_numbers")) or {} techage.add_to_set(numbers, number) - user:set_attribute("techage_prog_numbers", minetest.serialize(numbers)) + user:get_meta():set_string("techage_prog_numbers", minetest.serialize(numbers)) minetest.chat_send_player(user:get_player_name(), S("[TechAge Programmer] number").." "..number.." read") else minetest.chat_send_player(user:get_player_name(), S("[TechAge Programmer] Unknown node on").." "..minetest.pos_to_string(pos)) @@ -52,8 +52,8 @@ local function program_numbers(itemstack, placer, pointed_thing) local pos = pointed_thing.under if pos then local meta = M(pos) - local numbers = minetest.deserialize(placer:get_attribute("techage_prog_numbers")) or {} - placer:set_attribute("techage_prog_numbers", nil) + local numbers = minetest.deserialize(placer:get_meta():get_string("techage_prog_numbers")) or {} + placer:get_meta():set_string("techage_prog_numbers", nil) local player_name = placer:get_player_name() if meta and meta:get_string("owner") ~= player_name then minetest.chat_send_player(player_name, S("[TechAge Programmer] foreign or unknown node!")) diff --git a/techage/ta1_watermill/sluice.lua b/techage/ta1_watermill/sluice.lua index 1ea0245..c5048e6 100644 --- a/techage/ta1_watermill/sluice.lua +++ b/techage/ta1_watermill/sluice.lua @@ -49,6 +49,10 @@ local function has_water(pos, facedir) end local function on_rightclick(pos, node, clicker, itemstack, pointed_thing) + if minetest.is_protected(pos, clicker:get_player_name()) then + return + end + local pos2 = vector.add(pos, {x = 0, y = -1, z = 0}) local node2 = minetest.get_node(pos2) local pos3, res = has_water(pos2, node2.param2)