aboutsummaryrefslogtreecommitdiff
path: root/advtrains/techage.lua
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains/techage.lua')
-rw-r--r--advtrains/techage.lua227
1 files changed, 227 insertions, 0 deletions
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 = <capacity_in_liquid_units>" 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