--[[ TechAge ======= Copyright (C) 2019-2021 Joachim Stolberg GPL v3 See LICENSE.txt for more information Winch for TA2 gravity-based energy storage ]]-- -- for lazy programmers local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end local S2P = minetest.string_to_pos local M = minetest.get_meta local S = techage.S local MIN_LOAD = 99 -- 1 stack local MAX_ROPE_LEN = 10 local CYCLE_TIME = 2 local Axle = techage.Axle local power = networks.power local control = networks.control local function chest_pos(pos) local pos1 = {x = pos.x, y = pos.y - 1, z = pos.z} -- start pos local pos2 = {x = pos.x, y = pos.y - 1 - MAX_ROPE_LEN, z = pos.z} -- end pos local _, pos3 = minetest.line_of_sight(pos1, pos2) return pos3 or pos2 end local function chest_load(nvm, pos) local amount = 0 local inv = minetest.get_inventory({type = "node", pos = pos}) nvm.stored_items = {} for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) nvm.stored_items[i] = {name = stack:get_name(), count = stack:get_count()} amount = amount + stack:get_count() end return amount * 3 end local function chest_full(pos) local nvm = techage.get_nvm(pos) local pos1 = chest_pos(pos) local node = minetest.get_node(pos1) if node.name == "techage:ta2_weight_chest" then return chest_load(nvm, pos1) >= MIN_LOAD end end local function add_chest_entity(pos, nvm) local mem = techage.get_mem(pos) local length if not nvm.capa or nvm.capa == 0 then length = (nvm.length or MAX_ROPE_LEN) * (1 - (nvm.load or 0)) else length = (nvm.length or MAX_ROPE_LEN) * (1 - (nvm.load or 0) / nvm.capa) end local y = pos.y - length - 1 techage.renew_rope(pos, length, true) if mem.obj then mem.obj:remove() end mem.obj = minetest.add_entity({x = pos.x, y = y, z = pos.z}, "techage:ta2_weight_chest_entity") end -- Add chest node, remove chest entity instead local function add_chest(pos) local mem = techage.get_mem(pos) local nvm = techage.get_nvm(pos) if mem.obj then mem.obj:remove() mem.obj = nil end if nvm.capa and nvm.capa >= MIN_LOAD then local pos1 = {x = pos.x, y = pos.y - (nvm.length or 1) - 1, z = pos.z} minetest.add_node(pos1, {name = "techage:ta2_weight_chest", param2 = 0}) local ndef = minetest.registered_nodes["techage:ta2_weight_chest"] ndef.on_construct(pos1) ndef.after_place_node(pos1) local inv = minetest.get_inventory({type = "node", pos = pos1}) for i, item in ipairs(nvm.stored_items or {}) do inv:set_stack("main", i, item) end end nvm.capa = 0 end -- Remove chest node, add rope and chest entity instead local function remove_chest(pos) local mem = techage.get_mem(pos) local nvm = techage.get_nvm(pos) local pos1 = chest_pos(pos) local mass = chest_load(nvm, pos1) if mass > 0 then nvm.length = pos.y - pos1.y - 1 nvm.capa = mass * nvm.length / MAX_ROPE_LEN minetest.remove_node(pos1) mem.obj = minetest.add_entity(pos1, "techage:ta2_weight_chest_entity") techage.renew_rope(pos, nvm.length) return true end end minetest.register_node("techage:ta2_winch", { description = S("TA2 Winch"), tiles = { -- up, down, right, left, back, front "techage_filling_ta2.png^techage_appl_arrow2.png^techage_frame_ta2.png^[transformR270", "techage_filling_ta2.png^techage_appl_arrow2.png^techage_frame_ta2.png^techage_appl_winch_hole.png^[transformR270", "techage_filling_ta2.png^techage_axle_gearbox.png^techage_frame_ta2.png", "techage_filling_ta2.png^techage_appl_winch.png^techage_frame_ta2.png", "techage_filling_ta2.png^techage_appl_winch.png^techage_frame_ta2.png", "techage_filling_ta2.png^techage_appl_winch.png^techage_frame_ta2.png", }, after_place_node = function(pos, placer) local nvm = techage.get_nvm(pos) local outdir = networks.side_to_outdir(pos, "R") M(pos):set_int("outdir", outdir) Axle:after_place_node(pos, {outdir}) minetest.get_node_timer(pos):start(CYCLE_TIME) techage.renew_rope(pos, MAX_ROPE_LEN - 1) end, on_timer = function(pos, elapsed) local nvm = techage.get_nvm(pos) local outdir = M(pos):get_int("outdir") nvm.capa = nvm.capa or 1 nvm.load = nvm.load or 0 if nvm.blocked then -- Keep the network active power.get_storage_load(pos, Axle, outdir, nvm.capa) return true end if not nvm.running and power.power_available(pos, Axle, outdir) and chest_full(pos) then remove_chest(pos) nvm.running = true power.start_storage_calc(pos, Axle, outdir) elseif nvm.running and nvm.load < 2 and not power.power_available(pos, Axle, outdir) then add_chest(pos) nvm.running = false power.start_storage_calc(pos, Axle, outdir) end if nvm.running then nvm.load = power.get_storage_load(pos, Axle, outdir, nvm.capa) or 0 if nvm.load > 2 then add_chest_entity(pos, nvm) end else techage.renew_rope(pos, 50) end return true end, after_dig_node = function(pos, oldnode, oldmetadata) add_chest(pos) techage.del_rope(pos) local outdir = tonumber(oldmetadata.fields.outdir or 0) power.start_storage_calc(pos, Axle, outdir) Axle:after_dig_node(pos, {outdir}) techage.del_mem(pos) end, get_storage_data = function(pos, outdir, tlib2) local nvm = techage.get_nvm(pos) nvm.capa = nvm.capa or 1 if nvm.running and not nvm.blocked then return {level = (nvm.load or 0) / nvm.capa, capa = nvm.capa} end end, paramtype2 = "facedir", groups = {choppy=2, cracky=2, crumbly=2}, is_ground_content = false, sounds = default.node_sound_wood_defaults(), }) power.register_nodes({"techage:ta2_winch"}, Axle, "sto", {"R"}) techage.register_node({"techage:ta2_winch"}, { on_node_load = function(pos, node) minetest.get_node_timer(pos):start(CYCLE_TIME) local nvm = techage.get_nvm(pos) if nvm.running then add_chest_entity(pos, nvm) end end, }) control.register_nodes({"techage:ta2_winch"}, { on_receive = function(pos, tlib2, topic, payload) --print("on_receive", topic) local nvm = techage.get_nvm(pos) if topic == "on" then nvm.blocked = false local outdir = M(pos):get_int("outdir") power.start_storage_calc(pos, Axle, outdir) elseif topic == "off" then nvm.blocked = true local outdir = M(pos):get_int("outdir") power.start_storage_calc(pos, Axle, outdir) end end, } ) minetest.register_craft({ output = "techage:ta2_winch", recipe = { {"farming:string", "farming:string", "farming:string"}, {"farming:string", "techage:gearbox", "farming:string"}, {"farming:string", "farming:string", "farming:string"}, }, })