From d6a1cbe81664aa0afa3ff4c97d01493612546bf5 Mon Sep 17 00:00:00 2001 From: orwell96 Date: Tue, 18 Jul 2023 00:08:19 +0200 Subject: Skeleton support for Techage Liquids in tank cars TODO: - Pretty nodes for loader and unloader - Display liquid contents in formspec - Update basic_trains accordingly --- advtrains/init.lua | 6 +- advtrains/mod.conf | 2 +- advtrains/techage.lua | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++ advtrains/wagons.lua | 5 ++ 4 files changed, 237 insertions(+), 3 deletions(-) create mode 100644 advtrains/techage.lua diff --git a/advtrains/init.lua b/advtrains/init.lua index a7e5764..a2c2def 100644 --- a/advtrains/init.lua +++ b/advtrains/init.lua @@ -222,10 +222,12 @@ dofile(advtrains.modpath.."/craft_items.lua") dofile(advtrains.modpath.."/log.lua") dofile(advtrains.modpath.."/passive.lua") -if mesecon then +if minetest.global_exists("mesecon") then dofile(advtrains.modpath.."/p_mesecon_iface.lua") end - +if minetest.global_exists("techage") then + dofile(advtrains.modpath.."/techage.lua") +end dofile(advtrains.modpath.."/lzb.lua") diff --git a/advtrains/mod.conf b/advtrains/mod.conf index 5808d1a..597a642 100644 --- a/advtrains/mod.conf +++ b/advtrains/mod.conf @@ -4,4 +4,4 @@ description=Core system for realistic trains in Minetest author=orwell96 depends=serialize_lib -optional_depends=mesecons,mesecons_switch,digtron +optional_depends=mesecons,mesecons_switch,digtron,techage diff --git a/advtrains/techage.lua b/advtrains/techage.lua new file mode 100644 index 0000000..abd5987 --- /dev/null +++ b/advtrains/techage.lua @@ -0,0 +1,227 @@ +-- techage.lua +-- Tech-age specific features, loaded only when techage is found + +-- == Liquid features == -- +-- Tank wagons can get support for Techage liquids. +-- advtrains provides a "Tank car filling spigot" and a "Tank car unloading funnel" which are placed above resp. below the tracks. +-- They act as proxy nodes from/to which liquids can be pumped using the Techage pumps +-- Note: for tank cars to support filling with liquid, add the "techage_liquid_capacity = " property to the wagon definition. + +-- Get Techage variables +local Pipe = techage.LiquidPipe +local liquid = networks.liquid + +-- Nodes + + +-- checks for and gets a tank car at given reference position. Ref Pos must be the track this node relates to. +-- For a wagon to be valid it must be standing at the node in question +-- If found, returns liquid_info, capacity, wagon_id (where liquid_info is {name=..., amount=...} in same format as the techage tank nvms) +-- If not found, returns nil +local function get_tank_car_liquidinfo(ref_pos) + local trains = advtrains.occ.get_trains_at(ref_pos) + for train_id, index in pairs(trains) do + local train = advtrains.trains[train_id] + -- make sure that the train is stopped + if train.velocity == 0 then + local wagon_num, wid, data, offset_from_center = advtrains.get_wagon_at_index(train_id, index) + if wagon_num and offset_from_center < 1 then + -- this wagon is possibly a tank car. Check the wagon def + local _, proto = advtrains.get_wagon_prototype(data) + if proto.techage_liquid_capacity then + -- Found a tank car. Get its liquid info from the data table, create it if necessary + if not data.techage_liquid then + data.techage_liquid = {} + end + return data.techage_liquid, proto.techage_liquid_capacity, wid + end + end + end + end + return nil +end + +local function loader_relpos(pos) + return {x=pos.x, y=pos.y-3, z=pos.z} +end + +local function tankcar_put_liquid(pos, name, amount) + local lic, capa, wid = get_tank_car_liquidinfo(pos) + if lic then + if lic.name then + if lic.name ~= name then + -- different liquid than already in here - deny + return amount + end + -- else add the amount + lic.amount = lic.amount + amount + else + -- does not contain liquid yet, set name and amount to 0 + lic.name = name + lic.amount = amount + end + --atdebug("tankcar_put_liquid: put",name,amount,", now contains ",lic) + if lic.amount > capa then + -- capacity was hit, reject too much liquid + local reject = lic.amount - capa + lic.amount = capa + --atdebug("tankcar_put_liquid: over capa", capa, ", rejects ", reject) + return reject + end + return 0 + end + return amount +end + + +local function unloader_relpos(pos) + return {x=pos.x, y=pos.y+1, z=pos.z} +end + +local function tankcar_take_liquid(pos, name, amount) + local lic, capa, wid = get_tank_car_liquidinfo(pos) + if lic then + if lic.name then + -- note: name parameter may be nil (aka any), then do not prevent + if name and lic.name ~= name then + -- different liquid than already in here - deny + return 0 + end + else + -- does not contain liquid, nothing to take + return 0 + end + if lic.amount <= amount then + -- pumping last bit of liquid + local rest, oldname = lic.amount, lic.name + lic.amount = 0 + lic.name = nil -- reset the name since car is now empty + --atdebug("tankcar_take_liquid: took",name,amount,", now empty") + return rest, oldname + end + -- no underflow, subtract + lic.amount = lic.amount - amount + --atdebug("tankcar_take_liquid: took",name,amount,", now left ",lic) + return amount, lic.name + end + return 0 -- no wagon here +end + +minetest.register_node("advtrains:ta_liquid_loader", { + description = attrans("Tank Car Filling Spigot"), + tiles = { + "techage_gaspipe_knee2.png", + "techage_gaspipe_hole2.png^[transformR180", + "techage_gaspipe_knee.png^[transformR270", + "techage_gaspipe_knee.png", + "techage_gaspipe_knee2.png", + "techage_gaspipe_hole2.png", + }, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_tube(pos, oldnode, oldmetadata) + end, + + paramtype2 = "facedir", -- important! + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-1/8, -4/8, -1/8, 1/8, 1/8, 1/8}, + {-2/8, -0.5, -2/8, 2/8, -13/32, 2/8}, + {-1/8, -1/8, -4/8, 1/8, 1/8, -1/8}, + {-2/8, -2/8, -0.5, 2/8, 2/8, -13/32}, + }, + }, + on_rotate = screwdriver.disallow, -- important! + paramtype = "light", + use_texture_alpha = techage.CLIP, + sunlight_propagates = true, + is_ground_content = false, + groups = {crumbly = 2, cracky = 2, snappy = 2}, + sounds = default.node_sound_metal_defaults(), + drop = "advtrains:ta_liquid_loader", +}) + +liquid.register_nodes({"advtrains:ta_liquid_loader"}, + Pipe, "tank", nil, { + capa = 42, -- should provide the type of liquid anyway, because pump uses it to check whether it can pump here + peek = function(pos, indir) + local lic, capa, wid = get_tank_car_liquidinfo(loader_relpos(pos)) + --atdebug("loader peeked: ", lic, capa) + if lic and lic.name and lic.amount > 0 then + return lic.name + end + return nil + end, + put = function(pos, indir, name, amount) + return tankcar_put_liquid(loader_relpos(pos), name, amount) + end, + take = function(pos, indir, name, amount) + return 0 -- cannot take anything from the loader + end, + untake = function(pos, indir, name, amount) + return tankcar_put_liquid(loader_relpos(pos), name, amount) + end, + } +) + +minetest.register_node("advtrains:ta_liquid_unloader", { + description = attrans("Tank Car Unloading Drain Funnel"), + tiles = { + "techage_gaspipe_knee2.png", + "techage_gaspipe_hole2.png^[transformR180", + "techage_gaspipe_knee.png^[transformR270", + "techage_gaspipe_knee.png", + "techage_gaspipe_knee2.png", + "techage_gaspipe_hole2.png", + }, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_tube(pos, oldnode, oldmetadata) + end, + + paramtype2 = "facedir", -- important! + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-1/8, -4/8, -1/8, 1/8, 1/8, 1/8}, + {-2/8, -0.5, -2/8, 2/8, -13/32, 2/8}, + {-1/8, -1/8, -4/8, 1/8, 1/8, -1/8}, + {-2/8, -2/8, -0.5, 2/8, 2/8, -13/32}, + }, + }, + on_rotate = screwdriver.disallow, -- important! + paramtype = "light", + use_texture_alpha = techage.CLIP, + sunlight_propagates = true, + is_ground_content = false, + groups = {crumbly = 2, cracky = 2, snappy = 2}, + sounds = default.node_sound_metal_defaults(), + drop = "advtrains:ta_liquid_unloader", +}) + +liquid.register_nodes({"advtrains:ta_liquid_unloader"}, + Pipe, "tank", nil, { + capa = 42, -- should be ignored, lets see if it really is + peek = function(pos, indir) + local lic, capa, wid = get_tank_car_liquidinfo(unloader_relpos(pos)) + --atdebug("unloader peeked: ", lic, capa) + if lic and lic.name and lic.amount > 0 then + return lic.name + end + return nil + end, + put = function(pos, indir, name, amount) + return amount -- cannot put here + end, + take = function(pos, indir, name, amount) + return tankcar_take_liquid(unloader_relpos(pos), name, amount) + end, + untake = function(pos, indir, name, amount) + -- untake has to work like a put would! + return tankcar_put_liquid(loader_relpos(pos), name, amount) + end, + } +) \ No newline at end of file diff --git a/advtrains/wagons.lua b/advtrains/wagons.lua index b0fb575..d1812aa 100644 --- a/advtrains/wagons.lua +++ b/advtrains/wagons.lua @@ -364,6 +364,11 @@ function wagon:on_step(dtime) outside = outside .."\n!!! Train off track !!!" end + -- liquid container (temporary solution): display liquid contents in infotext + if self.techage_liquid_capacity and data.techage_liquid and data.techage_liquid.name then + outside = outside .."\nLiquid: "..data.techage_liquid.name..", "..data.techage_liquid.amount.." units" + end + if self.infotext_cache~=outside then self.object:set_properties({infotext=outside}) self.infotext_cache=outside -- cgit v1.2.3