From d342a3d6695474ec0173813c4fb899e1c9c2b8a4 Mon Sep 17 00:00:00 2001 From: Joachim Stolberg Date: Sun, 26 May 2019 23:22:29 +0200 Subject: [PATCH] lamps, oil and oil explorer added --- basic_machines/gravelrinser.lua | 1 - basis/node_states.lua | 1 - coal_power_station/akkubox.lua | 4 - init.lua | 6 + iron_age/coalburner.lua | 1 + iron_age/meltingpot.lua | 19 +- lamps/ceilinglamp.lua | 68 +++++ lamps/industriallamp1.lua | 68 +++++ lamps/industriallamp2.lua | 70 +++++ lamps/lib.lua | 61 ++++- lamps/streetlamp.lua | 14 - oil/explore.lua | 304 +++++++++++++++++++++ oil/storage.lua | 68 +++++ power/power.lua | 10 +- power/powerswitch.lua | 1 + sounds/techage_explore.ogg | Bin 0 -> 7275 bytes steam_engine/boiler.lua | 1 - test/test.lua | 105 +------ textures/techage_appl_oilexplorer.png | Bin 0 -> 451 bytes textures/techage_appl_oilexplorer_top.png | Bin 0 -> 178 bytes textures/techage_appl_oilexplorer_top4.png | Bin 0 -> 363 bytes textures/techage_ceilinglamp.png | Bin 0 -> 551 bytes textures/techage_ceilinglamp_bottom.png | Bin 0 -> 591 bytes textures/techage_ceilinglamp_top.png | Bin 0 -> 158 bytes textures/techage_industriallamp1.png | Bin 0 -> 268 bytes textures/techage_industriallamp1_on.png | Bin 0 -> 327 bytes textures/techage_industriallamp2.png | Bin 0 -> 229 bytes textures/techage_industriallamp2_on.png | Bin 0 -> 201 bytes textures/techage_industriallamp_inv1.png | Bin 0 -> 429 bytes textures/techage_industriallamp_inv2.png | Bin 0 -> 657 bytes textures/techage_oil.png | Bin 0 -> 311 bytes textures/techage_oil_animated.png | Bin 0 -> 2529 bytes textures/techage_oil_inv.png | Bin 0 -> 313 bytes 33 files changed, 678 insertions(+), 124 deletions(-) create mode 100644 lamps/ceilinglamp.lua create mode 100644 lamps/industriallamp1.lua create mode 100644 lamps/industriallamp2.lua create mode 100644 oil/explore.lua create mode 100644 oil/storage.lua create mode 100644 sounds/techage_explore.ogg create mode 100644 textures/techage_appl_oilexplorer.png create mode 100644 textures/techage_appl_oilexplorer_top.png create mode 100644 textures/techage_appl_oilexplorer_top4.png create mode 100644 textures/techage_ceilinglamp.png create mode 100644 textures/techage_ceilinglamp_bottom.png create mode 100644 textures/techage_ceilinglamp_top.png create mode 100644 textures/techage_industriallamp1.png create mode 100644 textures/techage_industriallamp1_on.png create mode 100644 textures/techage_industriallamp2.png create mode 100644 textures/techage_industriallamp2_on.png create mode 100644 textures/techage_industriallamp_inv1.png create mode 100644 textures/techage_industriallamp_inv2.png create mode 100644 textures/techage_oil.png create mode 100644 textures/techage_oil_animated.png create mode 100644 textures/techage_oil_inv.png diff --git a/basic_machines/gravelrinser.lua b/basic_machines/gravelrinser.lua index d814c9b..cde3242 100644 --- a/basic_machines/gravelrinser.lua +++ b/basic_machines/gravelrinser.lua @@ -158,7 +158,6 @@ local function washing(pos, crd, mem, inv) end local function keep_running(pos, elapsed) - print("keep_running") local mem = tubelib2.get_mem(pos) local crd = CRD(pos) local inv = M(pos):get_inventory() diff --git a/basis/node_states.lua b/basis/node_states.lua index 0b984f0..a053d60 100644 --- a/basis/node_states.lua +++ b/basis/node_states.lua @@ -125,7 +125,6 @@ local function swap_node(pos, name) if node.name == name then return end - print("swap_node", name) node.name = name minetest.swap_node(pos, node) end diff --git a/coal_power_station/akkubox.lua b/coal_power_station/akkubox.lua index 53809c0..f73fea9 100644 --- a/coal_power_station/akkubox.lua +++ b/coal_power_station/akkubox.lua @@ -66,7 +66,6 @@ local State = techage.NodeStates:new({ -- Pass1: Power balance calculation local function on_power_pass1(pos, mem) - print("on_power_pass1", mem.charging) if State:is_active(mem) and mem.capa > POWER_HYSTERESIS then mem.correction = POWER_CONSUMPTION -- uncharging else @@ -77,7 +76,6 @@ end -- Pass2: Power balance adjustment local function on_power_pass2(pos, mem, sum) - print("on_power_pass2", mem.charging, sum) if State:is_active(mem) then if sum > mem.correction + POWER_CONSUMPTION and mem.capa < POWER_MAX_LOAD - POWER_HYSTERESIS then @@ -100,14 +98,12 @@ end -- Pass3: Power balance result local function on_power_pass3(pos, mem, sum) - print("on_power_pass3", mem.charging, sum) mem.power_result = sum end local function node_timer(pos, elapsed) local mem = tubelib2.get_mem(pos) - print("node_timer", mem.charging, mem.capa) if State:is_active(mem) then mem.capa = mem.capa or 0 if mem.charging == true then diff --git a/init.lua b/init.lua index dae9f9a..f12860c 100644 --- a/init.lua +++ b/init.lua @@ -110,6 +110,12 @@ else dofile(MP.."/lamps/lib.lua") dofile(MP.."/lamps/simplelamp.lua") dofile(MP.."/lamps/streetlamp.lua") + dofile(MP.."/lamps/ceilinglamp.lua") + dofile(MP.."/lamps/industriallamp1.lua") + dofile(MP.."/lamps/industriallamp2.lua") + + -- Oil + dofile(MP.."/oil/explore.lua") --dofile(MP.."/test/generator.lua") diff --git a/iron_age/coalburner.lua b/iron_age/coalburner.lua index c45f49b..dbc3e48 100644 --- a/iron_age/coalburner.lua +++ b/iron_age/coalburner.lua @@ -187,6 +187,7 @@ function techage.start_burner(pos, playername) end function techage.keep_running_burner(pos) + print("keep_running_burner") local meta = minetest.get_meta(pos) local height = meta:get_int("height") remove_flame(pos, height) diff --git a/iron_age/meltingpot.lua b/iron_age/meltingpot.lua index 4c76a06..dfa9ebd 100644 --- a/iron_age/meltingpot.lua +++ b/iron_age/meltingpot.lua @@ -209,11 +209,22 @@ local function get_heat(pos) pos.y = pos.y - 1 local node = minetest.get_node(pos) local meta = minetest.get_meta(pos) - pos.y = pos.y + 1 - if minetest.get_item_group(node.name, "techage_flame") > 0 then - heat = meta:get_int("heat") + print("get_heat1", minetest.get_item_group(node.name, "techage_flame")) + if minetest.get_item_group(node.name, "techage_flame") == 0 then + pos.y = pos.y + 1 + return 0 end - return heat + + pos.y = pos.y - 1 + node = minetest.get_node(pos) + pos.y = pos.y + 2 + print("get_heat2", node.name, minetest.get_item_group(node.name, "techage_flame")) + if minetest.get_item_group(node.name, "techage_flame") == 0 and + node.name ~= "techage:charcoal_burn" then + return 0 + end + + return meta:get_int("heat") end -- Start melting if heat is ok AND source items available diff --git a/lamps/ceilinglamp.lua b/lamps/ceilinglamp.lua new file mode 100644 index 0000000..8edf3b7 --- /dev/null +++ b/lamps/ceilinglamp.lua @@ -0,0 +1,68 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + TA3/TA4 Ceiling Lamp + +]]-- + +-- Load support for intllib. +local MP = minetest.get_modpath("techage") +local I,_ = dofile(MP.."/intllib.lua") + +techage.register_lamp("techage:ceilinglamp", { + description = "TA Ceiling Lamp", + tiles = { + -- up, down, right, left, back, front + 'techage_ceilinglamp_top.png', + 'techage_ceilinglamp_bottom.png', + 'techage_ceilinglamp.png', + 'techage_ceilinglamp.png', + 'techage_ceilinglamp.png', + 'techage_ceilinglamp.png', + 'techage_ceilinglamp.png', + 'techage_ceilinglamp.png', + }, + + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-5/16, -7/16, -5/16, 5/16, -5/16, 5/16}, + {-4/16, -8/16, -4/16, 4/16, -7/16, 4/16}, + }, + }, + +},{ + description = "TA Ceiling Lamp", + tiles = { + -- up, down, right, left, back, front + 'techage_ceilinglamp_top.png', + 'techage_ceilinglamp_bottom.png', + 'techage_ceilinglamp.png', + 'techage_ceilinglamp.png', + 'techage_ceilinglamp.png', + 'techage_ceilinglamp.png', + }, + + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-5/16, -7/16, -5/16, 5/16, -5/16, 5/16}, + {-4/16, -8/16, -4/16, 4/16, -7/16, 4/16}, + }, + }, +}) + +minetest.register_craft({ + type = "shapeless", + output = "techage:ceilinglamp_off 3", + recipe = {"techage:simplelamp_off", "default:wood", "default:glass"}, +}) diff --git a/lamps/industriallamp1.lua b/lamps/industriallamp1.lua new file mode 100644 index 0000000..75db430 --- /dev/null +++ b/lamps/industriallamp1.lua @@ -0,0 +1,68 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + TA3/TA4 Industrial Lamp 1 + +]]-- + +-- Load support for intllib. +local MP = minetest.get_modpath("techage") +local I,_ = dofile(MP.."/intllib.lua") + +techage.register_lamp("techage:industriallamp1", { + description = "TA Industrial Lamp 1", + inventory_image = 'techage_industriallamp_inv1.png', + tiles = { + -- up, down, right, left, back, front + 'techage_industriallamp1.png', + 'techage_industriallamp1.png', + 'techage_industriallamp1.png^[transformR180', + 'techage_industriallamp1.png^[transformR180', + 'techage_industriallamp1.png', + 'techage_industriallamp1.png', + }, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-8/16, -8/16, -3/32, -6/16, -9/32, 3/32}, + { 6/16, -8/16, -3/32, 8/16, -9/32, 3/32}, + {-6/16, -7/16, -1/16, 6/16, -5/16, 1/16}, + }, + }, +},{ + tiles = { + -- up, down, right, left, back, front + 'techage_industriallamp1_on.png', + 'techage_industriallamp1_on.png', + 'techage_industriallamp1_on.png^[transformR180', + 'techage_industriallamp1_on.png^[transformR180', + 'techage_industriallamp1_on.png', + 'techage_industriallamp1_on.png', + }, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-8/16, -8/16, -3/32, -6/16, -9/32, 3/32}, + { 6/16, -8/16, -3/32, 8/16, -9/32, 3/32}, + {-6/16, -7/16, -1/16, 6/16, -5/16, 1/16}, + }, + }, +}) + +minetest.register_craft({ + output = "techage:industriallamp1_off 2", + recipe = { + {"", "", ""}, + {"default:glass", "techage:simplelamp_off", "dye:grey"}, + {"basic_materials:plastic_strip", "default:copper_ingot", "basic_materials:plastic_strip"}, + }, +}) diff --git a/lamps/industriallamp2.lua b/lamps/industriallamp2.lua new file mode 100644 index 0000000..4a3ecc9 --- /dev/null +++ b/lamps/industriallamp2.lua @@ -0,0 +1,70 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + TA3/TA4 Industrial Lamp 2 + +]]-- + +-- Load support for intllib. +local MP = minetest.get_modpath("techage") +local I,_ = dofile(MP.."/intllib.lua") + +local size = {x = 8/32, y = 8/32, z = 5/32} + +techage.register_lamp("techage:industriallamp2", { + description = "TA Industrial Lamp 2", + inventory_image = 'techage_industriallamp_inv2.png', + tiles = { + -- up, down, right, left, back, front + 'techage_industriallamp2.png', + 'techage_industriallamp2.png', + 'techage_industriallamp2.png^[transformR180', + 'techage_industriallamp2.png^[transformR180', + 'techage_industriallamp2.png', + 'techage_industriallamp2.png', + }, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-8/32, -16/32, -4/32, 8/32, -9/32, 4/32}, + {-7/32, -16/32, -5/32, 7/32, -9/32, 5/32}, + {-7/32, -9/32, -4/32, 7/32, -8/32, 4/32}, + }, + }, +},{ + tiles = { + -- up, down, right, left, back, front + 'techage_industriallamp2_on.png', + 'techage_industriallamp2_on.png', + 'techage_industriallamp2_on.png^[transformR180', + 'techage_industriallamp2_on.png^[transformR180', + 'techage_industriallamp2_on.png', + 'techage_industriallamp2_on.png', + }, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-8/32, -16/32, -4/32, 8/32, -9/32, 4/32}, + {-7/32, -16/32, -5/32, 7/32, -9/32, 5/32}, + {-7/32, -9/32, -4/32, 7/32, -8/32, 4/32}, + }, + }, +}) + +minetest.register_craft({ + output = "techage:industriallamp2_off 2", + recipe = { + {"default:glass", "default:glass", ""}, + {"techage:simplelamp_off", "dye:black", ""}, + {"basic_materials:steel_bar", "basic_materials:steel_bar", ""}, + }, +}) diff --git a/lamps/lib.lua b/lamps/lib.lua index ab27d6b..79a1b4b 100644 --- a/lamps/lib.lua +++ b/lamps/lib.lua @@ -7,6 +7,27 @@ local POWER_CONSUMPTION = 1 local Power = techage.ElectricCable +-- Input data to generate the Param2ToDir table +local Input = { + 8,9,10,11, -- 1 + 16,17,18,19, -- 2 + 4,5,6,7, -- 3 + 12,13,14,15, -- 4 + 0,1,2,3, -- 5 + 20,21,22,23, -- 6 +} + +local Param2Dir = {} +for idx,val in ipairs(Input) do + Param2Dir[val] = math.floor((idx - 1) / 4) + 1 +end + +local function rotate(param2) + local offs = math.floor(param2 / 4) * 4 + local rot = ((param2 % 4) + 1) % 4 + return offs + rot +end + local function swap_node(pos, postfix) local node = Power:get_node_lvm(pos) local parts = string.split(node.name, "_") @@ -27,7 +48,6 @@ local function on_power_pass1(pos, mem) end local function on_power_pass2(pos, mem, sum) - local node = minetest if sum > 0 and mem.running then swap_node(pos, "on") return 0 @@ -50,12 +70,50 @@ local function lamp_on_rightclick(pos, node, clicker) techage.power.power_distribution(pos) end +local function on_rotate(pos, node, user, mode, new_param2) + if minetest.is_protected(pos, user:get_player_name()) then + return false + end + node.param2 = rotate(node.param2) + minetest.swap_node(pos, node) + return true +end + +local function on_place(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + return minetest.rotate_and_place(itemstack, placer, pointed_thing) +end + +local function determine_power_side(pos, node) + return {tubelib2.Turn180Deg[Param2Dir[node.param2] or 1]} +end + function techage.register_lamp(basename, ndef_off, ndef_on) ndef_off.on_construct = tubelib2.init_mem ndef_off.on_rightclick = lamp_on_rightclick + ndef_off.on_rotate = on_rotate + ndef_off.on_place = on_place + ndef_off.paramtype = "light" + ndef_off.light_source = 0 + ndef_off.sunlight_propagates = true + ndef_off.paramtype2 = "facedir" + ndef_off.groups = {choppy=2, cracky=2, crumbly=2} + ndef_off.is_ground_content = false + ndef_off.sounds = default.node_sound_glass_defaults() ndef_on.on_construct = tubelib2.init_mem ndef_on.on_rightclick = lamp_on_rightclick + ndef_on.on_rotate = on_rotate + ndef_on.paramtype = "light" + ndef_on.light_source = minetest.LIGHT_MAX + ndef_on.sunlight_propagates = true + ndef_on.paramtype2 = "facedir" + ndef_on.diggable = false + ndef_on.groups = {not_in_creative_inventory=1} + ndef_on.is_ground_content = false + ndef_on.sounds = default.node_sound_glass_defaults() minetest.register_node(basename.."_off", ndef_off) minetest.register_node(basename.."_on", ndef_on) @@ -64,5 +122,6 @@ function techage.register_lamp(basename, ndef_off, ndef_on) on_power_pass1 = on_power_pass1, on_power_pass2 = on_power_pass2, power_network = Power, + conn_sides = determine_power_side, -- will be handled by clbk function }) end diff --git a/lamps/streetlamp.lua b/lamps/streetlamp.lua index f533a0e..a986a2e 100644 --- a/lamps/streetlamp.lua +++ b/lamps/streetlamp.lua @@ -39,13 +39,6 @@ techage.register_lamp("techage:streetlamp", { type = "fixed", fixed = {-8/16, -8/16, -8/16, 8/16, 8/16, 8/16}, }, - paramtype = "light", - light_source = 0, - sunlight_propagates = true, - paramtype2 = "facedir", - groups = {choppy=2, cracky=2, crumbly=2}, - is_ground_content = false, - sounds = default.node_sound_glass_defaults(), },{ description = "TA Street Lamp", tiles = { @@ -67,13 +60,6 @@ techage.register_lamp("techage:streetlamp", { type = "fixed", fixed = {-8/16, -8/16, -8/16, 8/16, 8/16, 8/16}, }, - paramtype = "light", - light_source = minetest.LIGHT_MAX, - sunlight_propagates = true, - paramtype2 = "facedir", - groups = {crumbly=0, not_in_creative_inventory=1}, - is_ground_content = false, - sounds = default.node_sound_wood_defaults(), }) minetest.register_craft({ diff --git a/oil/explore.lua b/oil/explore.lua new file mode 100644 index 0000000..1d400bd --- /dev/null +++ b/oil/explore.lua @@ -0,0 +1,304 @@ +-- for lazy programmers +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local P = minetest.string_to_pos +local M = minetest.get_meta + +-- Load support for intllib. +local MP = minetest.get_modpath("techage") +local I,IS = dofile(MP.."/intllib.lua") + + +local PROBABILITY = 2 +local OIL_MIN = 1000 +local OIL_MAX = 20000 +local DEPTH_MIN = (16 * 7) - 8 +local DEPTH_MAX = (16 * 60) - 8 + +local seed = 1234 + +local function get_node_name(pos) + local node = minetest.get_node_or_nil(pos) + if node then + return node.name + end + local vm = minetest.get_voxel_manip() + local MinEdge, MaxEdge = vm:read_from_map(pos, pos) + local data = vm:get_data() + local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge}) + local idx = area:index(pos.x, pos.y, pos.z) + return minetest.get_name_from_content_id(data[idx]) +end + + +local function oil_amount(pos) + local block_key = seed + + math.floor((pos.z + 32768) / 16) * 4096 * 4096 + + math.floor((pos.y + 32768) / 16) * 4096 + + math.floor((pos.x + 32768) / 16) + math.randomseed(block_key) + math.random(); math.random(); math.random() + local has_oil = math.random(1,PROBABILITY) == 1 + if has_oil then + local amount = math.random(OIL_MIN, OIL_MAX) + return amount + end + return 0 +end + +local function center(coord) + return (math.floor(coord/16) * 16) + 8 +end + +local Invalid = { + "air", +} + +local function gen_oil_slice(pos1, posc, y, radius, data, id) + local y_offs = (y - pos1.y) * 16 + for x = posc.x - radius, posc.x + radius do + for z = posc.z - radius, posc.z + radius do + local idx = x - pos1.x + y_offs + (z - pos1.z) * 16 * 16 + data[idx] = id + end + end + return (radius * 2 + 1) * (radius * 2 + 1) +end + +local function gen_oil_bubble(pos1, posC, amount, data) + local id = minetest.get_content_id("techage:oil_source") + local radius = math.floor(math.pow(amount, 1.0/3) / 2) + local sum = 0 + for y = posC.y - radius, posC.y + radius do + sum = sum + gen_oil_slice(pos1, posC, y, radius + 1, data, id) + print(y, sum, amount) + if sum >= amount then break end + end +end + +local function useable_stone_block(data) + local valid = {} + for _,id in ipairs(data) do + if not valid[id] then + local itemname = minetest.get_name_from_content_id(id) + local ndef = minetest.registered_nodes[itemname] + if not ndef or not ndef.is_ground_content or Invalid[itemname] then + return false + end + valid[id] = true + end + end + return true +end + +local function explore_area(posS, depth, amount, player_name, pos1, pos2, posC) + if amount > 0 and M(posS):get_int("oil_amount") == 0 then + local vm = minetest.get_voxel_manip(pos1, pos2) + local data = vm:get_data() + + if useable_stone_block(data) then + gen_oil_bubble(pos1, posC, amount/10, data) + vm:set_data(data) + vm:write_to_map() + vm:update_map() + print("explore_area", S(pos1), S(pos2)) + else + amount = 0 + end + end + M(posS):set_int("oil_amount", amount) + minetest.chat_send_player(player_name, "[TA Oil] depth: "..tostring(depth).. + ", Oil: "..tostring(amount).." ") +end + +local function get_next_depth(pos) + local meta = M(pos) + local name = get_node_name(pos) + local depth = DEPTH_MIN + if name == "techage:oilstorage" then + if meta:get_int("oil_amount") == 0 then + depth = M(pos):get_int("exploration_depth") + 32 + else + depth = M(pos):get_int("exploration_depth") + end + else + minetest.set_node(pos, {name = "techage:oilstorage"}) + end + M(pos):set_int("exploration_depth", depth) + return depth +end + +local function emerge_area(pos, node, player_name) + node.name = "techage:oilexplorer_on" + minetest.swap_node(pos, node) + minetest.get_node_timer(pos):start(2.2) + + -- used to store the depth/amount info + local store_pos = {x = center(pos.x), y = -100, z = center(pos.z)} + local depth = get_next_depth(store_pos) + minetest.sound_play("techage_explore", { + pos = pos, + max_hear_distance = 8}) + local posC = {x = center(pos.x), y = center(pos.y-depth), z = center(pos.z)} + local amount = oil_amount(posC) + if amount > 0 then + local radius = 7 + local pos1 = {x = posC.x - radius, y = posC.y - radius, z = posC.z - radius} + local pos2 = {x = posC.x + radius, y = posC.y + radius, z = posC.z + radius} + print("emerge_area", S(pos1), S(pos2), S(posC)) + minetest.emerge_area(pos1, pos2) + minetest.after(2, explore_area, store_pos, depth, amount, player_name, pos1, pos2, posC) + else + minetest.after(2, explore_area, store_pos, depth, 0, player_name) + end +end + +--local function test(pos) +-- local posC = {x = center(pos.x), y = center(pos.y+20), z = center(pos.z)} +-- local pos1 = {x = posC.x - 8, y = posC.y - 8, z = posC.z - 8} +-- local pos2 = {x = posC.x + 7, y = posC.y + 7, z = posC.z + 7} +-- bubble(pos1, pos2, posC, math.random(10, 200)) +--end + +-- Used as storage for already explored blocks +-- Will be places -100 in the middle if a block (8,8) +minetest.register_node("techage:oilstorage", { + description = "TA Oil Storage", + tiles = {"default_stone.png"}, + groups = {not_in_creative_inventory=1}, + diggable = false, + is_ground_content = false, +}) + +minetest.register_node("techage:oilexplorer", { + description = "Oil Explorer", + tiles = { + "techage_filling_ta3.png^techage_appl_oilexplorer_top.png^techage_frame_ta3_top.png", + "techage_filling_ta3.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_oilexplorer.png", + }, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + emerge_area(pos, node, clicker:get_player_name()) + end, + + is_ground_content = false, + groups = {snappy=2,cracky=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("techage:oilexplorer_on", { + description = "Oil Explorer", + tiles = { + { + image = "techage_filling4_ta3.png^techage_appl_oilexplorer_top4.png^techage_frame4_ta3_top.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 1.0, + }, + }, + "techage_filling_ta3.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_oilexplorer.png", + }, + + on_timer = function(pos,elapsed) + local node = minetest.get_node(pos) + node.name = "techage:oilexplorer" + minetest.swap_node(pos, node) + end, + + is_ground_content = false, + groups = {snappy=2,cracky=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("techage:oil_source", { + description = "Oil Source", + drawtype = "liquid", + paramtype = "light", + + inventory_image = "techage_oil_inv.png", + tiles = { + { + name = "techage_oil_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 10 + } + }, + { + name = "techage_oil_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0 + } + } + }, + + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "techage:oil_flowing", + liquid_alternative_source = "techage:oil_source", + liquid_viscosity = 20, + liquid_range = 10, + post_effect_color = {a = 200, r = 1, g = 1, b = 1}, + groups = {liquid = 5}, +}) + + + +minetest.register_node("techage:oil_flowing", { + description = "Flowing Oil", + drawtype = "flowingliquid", + tiles = {"techage_oil.png"}, + special_tiles = { + { + name = "techage_oil_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 10, + }, + }, + { + name = "techage_oil_animated.png", + backface_culling = true, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 10, + }, + }, + }, + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drop = "", + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "techage:oil_flowing", + liquid_alternative_source = "techage:oil_source", + liquid_viscosity = 20, + liquid_range = 10, + post_effect_color = {a = 200, r = 1, g = 1, b = 1}, + groups = {liquid = 5, not_in_creative_inventory = 1}, +}) \ No newline at end of file diff --git a/oil/storage.lua b/oil/storage.lua new file mode 100644 index 0000000..34f81f5 --- /dev/null +++ b/oil/storage.lua @@ -0,0 +1,68 @@ +local S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local DAYS_VALID = (30 * 72) -- 30 real days + +local storage = minetest.get_mod_storage() + +local function data_maintenance() + minetest.log("info", "[MOD] minecart maintenance") + local day_count = minetest.get_day_count() + local tbl = storage:to_table() + for key,s in pairs(tbl.fields) do + local route = minetest.deserialize(s) + if not route.waypoints or not route.best_before or route.best_before < day_count then + storage:set_string(key, "") + else + minetest.log("info", "[minecart] Route: start="..key.." length="..#(route.waypoints)) + end + end +end +minetest.after(1, data_maintenance) + + +-- Store data of running carts +minecart.CartsOnRail = {} + +for key,val in pairs(minetest.deserialize(storage:get_string("CartsOnRail")) or {}) do + -- use invalid keys to force the cart spawning + minecart.CartsOnRail[-key] = val +end + +minetest.register_on_shutdown(function() + data_maintenance() + storage:set_string("CartsOnRail", minetest.serialize(minecart.CartsOnRail)) +end) + +-- All positions as "pos_to_string" string +--Routes = { +-- start_pos = { +-- waypoints = {{spos, svel}, {spos, svel}, ...}, +-- dest_pos = spos, +-- junctions = { +-- {spos = num}, +-- {spos = num}, +-- }, +-- best_before = num +-- }, +-- start_pos = {...}, +--} +local Routes = {} +local NEW_ROUTE = {waypoints = {}, junctions = {}} + +function minecart.store_route(key, route) + Routes[key] = table.copy(route) + Routes[key].best_before = minetest.get_day_count() + DAYS_VALID + storage:set_string(key, minetest.serialize(Routes[key])) +end + +function minecart.get_route(key) + Routes[key] = Routes[key] or minetest.deserialize(storage:get_string(key)) or NEW_ROUTE + Routes[key].best_before = minetest.get_day_count() + DAYS_VALID + return Routes[key] +end + +function minecart.del_route(key) + Routes[key] = nil -- remove from memory + storage:set_string(key, "") -- and from storage +end + + diff --git a/power/power.lua b/power/power.lua index 3717e76..a6f534f 100644 --- a/power/power.lua +++ b/power/power.lua @@ -55,8 +55,12 @@ end local function set_conn_dirs(pos, sides) local tbl = {} local node = minetest.get_node(pos) - for _,side in ipairs(sides) do - tbl[#tbl+1] = tubelib2.Turn180Deg[side_to_dir(node.param2, side)] + if type(sides) == "function" then + tbl = sides(pos, node) + else + for _,side in ipairs(sides) do + tbl[#tbl+1] = tubelib2.Turn180Deg[side_to_dir(node.param2, side)] + end end M(pos):set_string("power_dirs", minetest.serialize(tbl)) end @@ -125,7 +129,7 @@ local function power_distribution(pos) Route = {} pos_already_reached(pos) sum = connection_walk(pos, "on_power_pass3", sum) - print("power sum = "..sum) + --print("power sum = "..sum) end local function register_lbm(name) diff --git a/power/powerswitch.lua b/power/powerswitch.lua index 60f4ab1..6cd127e 100644 --- a/power/powerswitch.lua +++ b/power/powerswitch.lua @@ -110,6 +110,7 @@ minetest.register_node("techage:powerswitch_on", { switch_off(pos, node, clicker) end, + drop = "techage:powerswitch", on_rotate = screwdriver.disallow, paramtype = "light", sunlight_propagates = true, diff --git a/sounds/techage_explore.ogg b/sounds/techage_explore.ogg new file mode 100644 index 0000000000000000000000000000000000000000..fa714e0fb28372dcd3db99f1982dc581dcad070c GIT binary patch literal 7275 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 literal 0 HcmV?d00001 diff --git a/steam_engine/boiler.lua b/steam_engine/boiler.lua index c8b77bf..a4aee22 100644 --- a/steam_engine/boiler.lua +++ b/steam_engine/boiler.lua @@ -272,7 +272,6 @@ minetest.register_node("techage:boiler2", { end, power_signal_heat = function(pos) - print("power_signal_heat") local mem = tubelib2.get_mem(pos) mem.fire_trigger = true if not minetest.get_node_timer(pos):is_started() then diff --git a/test/test.lua b/test/test.lua index 794cc43..abbba07 100644 --- a/test/test.lua +++ b/test/test.lua @@ -1,95 +1,10 @@ --- for lazy programmers -local S = function(pos) if pos then return minetest.pos_to_string(pos) end end -local P = minetest.string_to_pos -local M = minetest.get_meta - -local function determine_water_dir(pos) - local pos1 = {x=pos.x+1, y=pos.y+1, z=pos.z} - local pos2 = {x=pos.x-1, y=pos.y+1, z=pos.z} - local pos3 = {x=pos.x, y=pos.y+1, z=pos.z+1} - local pos4 = {x=pos.x, y=pos.y+1, z=pos.z-1} - local node1 = minetest.get_node(pos1) - local node2 = minetest.get_node(pos2) - local node3 = minetest.get_node(pos3) - local node4 = minetest.get_node(pos4) - if node1.name == "default:water_flowing" and node2.name == "default:water_flowing" then - if node1.param2 > node2.param2 then - return 4 - elseif node1.param2 < node2.param2 then - return 2 - end - elseif node3.name == "default:water_flowing" and node4.name == "default:water_flowing" then - if node3.param2 > node4.param2 then - return 3 - elseif node3.param2 < node4.param2 then - return 1 - end - end - return 0 -end - -local function remove(obj) - obj:remove() -end - -local function velocity(obj, dir) - obj:set_velocity(vector.multiply(tubelib2.Dir6dToVector[dir], 0.3)) - minetest.after(10, remove, obj) -end - -local function node_timer(pos, elapsed) - local node = minetest.get_node(techage.get_pos(pos, 'U')) - local obj = minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, ItemStack("default:gold_lump")) - minetest.after(0.8, velocity, obj, M(pos):get_int("water_dir")) - return true -end - -minetest.register_node("techage:rinser", { - description = "TechAge Rinser", - tiles = { - -- up, down, right, left, back, front - { - image = "techage_appl_sieve4_top.png^techage_frame4_ta2_top.png", - backface_culling = false, - animation = { - type = "vertical_frames", - aspect_w = 32, - aspect_h = 32, - length = 2.0, - }, - }, - 'techage_electric_button.png', - }, - paramtype2 = "facedir", - groups = {cracky=2, crumbly=2, choppy=2}, - on_rotate = screwdriver.disallow, - is_ground_content = false, - - after_place_node = function(pos, placer) - minetest.get_node_timer(pos):start(5) - local dir = determine_water_dir(pos) - M(pos):set_int("water_dir", dir) - end, - - on_timer = node_timer, -}) - -local function remove_objects(pos) - for _, object in pairs(minetest.get_objects_inside_radius(pos, 1)) do - local lua_entity = object:get_luaentity() - if not object:is_player() and lua_entity and lua_entity.name == "__builtin:item" then - object:remove() - end - end -end - -minetest.register_lbm({ - label = "[techage] Rinser update", - name = "techage:update", - nodenames = {"techage:rinser"}, - run_at_every_load = true, - action = function(pos, node) - remove_objects({x=pos.x, y=pos.y+1, z=pos.z}) - end -}) - +local function bubble(pos1, pos2, posc, amount) + local radius = math.floor(math.pow(amount, 0.333)) + local xc = pos2.x - pos1.x + for x = posc.x - radius, posc.x + radius do + for y = posc.y - radius, posc.y + radius do + for z = posc.z - radius, posc.z + radius do + local idx = x - pos1.x + + (y - pos1.y) * 16 + + (z - pos1.z) * 16 * 16 +print() diff --git a/textures/techage_appl_oilexplorer.png b/textures/techage_appl_oilexplorer.png new file mode 100644 index 0000000000000000000000000000000000000000..26551a4ce3e656216f733ea9321ae533fbd477f0 GIT binary patch literal 451 zcmV;!0X+VRP)Uq zK~z}7?N+;Lgg_LXY{2bTET#)A2)1^yaTXgpOWX8*Lz?_Z$Ol;X1$h*v%?GULRwA|o zCeC=1YGET;9G!`<;OXW%_s;R0;V4227F;r1*WJs`SjjXq#ITj09x9soAy zo^#H3mSr8XEc;Nd03qa=F}5ArM=5>$7Yo|9C8B$SAh=aZ;5aafBB7ymU8hP3)ODQ# z0J3dcd7KMd5Qd>tSV(?|* z`uyj4>+9aHAETluo=npO&iRf~ ts_bxK1<>&pI^RZ7I1HGpY}08q%@)5S3);&5_;1nc4ik)EbNgG-Fc zf?5AAU*Z!>@;Py4rRwQtFN0@su1b`8p&?OvUjA5L~c#`DCC7XMsm# zF#`j)FbFd;%$g$s6l5>)^mS!_%qk_y#pCqF&K4;2!_&nvq~g}w+Yh;#6-3$|2ER$; z%|94_*J;b?(*0c=TZ1p3eN&sT^>bP0 Hl+XkK^~;$G literal 0 HcmV?d00001 diff --git a/textures/techage_ceilinglamp.png b/textures/techage_ceilinglamp.png new file mode 100644 index 0000000000000000000000000000000000000000..b9c9aec085d9d8dff72c3cbb89b986c87b05d54f GIT binary patch literal 551 zcmV+?0@(eDP)Ge00001bW%=J z06^y0W&i*H0b)x>L;#2d9Y_EG010qNS#tmY3ljhU3ljkVnw%H_000McNliru;{_HK zHysFi>B#^90YFJaK~y-)eN@So!ypWE_K>oL*pv_x{{JtBbl!AMpbG~JkYxlwff2J^ zoF`9~B%-lyTK8>w!5>D22N_{i=QJVVpuHX?_Fn>XW=<)E91{nA^A$Mei~k8ZJq*sV zEIHgKmnCxk6kq+by@t`igjcnkSqa!=Ijn+|afW@2xqiZ7Vb$CKEim~|uP5Wc>AJ|2 zgaM}QdWZANE7QlrbH2}q}w4-%|vI2jOuy80{v6M|QD zk@p)7kgaPtd9dI`sxvNKW?>p#1V6#j@`3dV_TYw-;|??CRG)?1K&Zy6zHkCFa^qF^ zzwyibvHQFq&z|&@OP?(LC+jM9hpS{RaEdvk$C|?Z5_*(l$?H&ZOWJkH3PT5~@k@A3 p+rCcD8bn!sfbtKx#m>S!wI7sCUd>9jYs>%u002ovPDHLkV1mi^^?U#T literal 0 HcmV?d00001 diff --git a/textures/techage_ceilinglamp_bottom.png b/textures/techage_ceilinglamp_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..f7635ef0936cc8ea6c8f2a5490297ef9eac93c5c GIT binary patch literal 591 zcmV-V0Tp+E5Q@ACBV^!M}j`1JSr_W1hu`TO|#{Q3L+`u_j?@W$WU00001bW%=J z06^y0W&i*H0b)x>L;#2d9Y_EG010qNS#tmY3ljhU3ljkVnw%H_000McNliru;shHM z7d5TlEp7k+0cc4?K~y-)&681*#2^Sn7sc@DM>4AcjQ79gHrcI-dxOzb#fr}c8}jw_ zA;ZwE(`u&KSxh8H%P&2#kA9);6z!rd;jriRVdyQ{u|G4EjmkWLR& zFZD+OvdXkGXW1o-5Q!MDH-OVUm%TCta0n+!NV`1>^V@UYE3x3XYytFDL6LaQr51+5 z1|~^GHp?wAZlFj3a8L!H_9$HNYvLAL4F!S1 z2C&W3*M3mc;TK4|5ObN`#!?IO020G&3V>1@?J4&)=Kw&E<^lx<;C4O$GB!$ukR-Nl zfW|*3(Q#(xUC~cHW=B?Ql5VprzBbopShaqRwuFdw`|C@^cNlLd#R?!^gS?;NX^UIO d(>~?5`~mS>C@^W6RQCV?002ovPDHLkV1fZ^3ef-n literal 0 HcmV?d00001 diff --git a/textures/techage_ceilinglamp_top.png b/textures/techage_ceilinglamp_top.png new file mode 100644 index 0000000000000000000000000000000000000000..835c1c371635f7212631ed0e7d1bf7715b7f0365 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnL3?x0byx0z;SkfJR9T^xl_H+M9WCijWi-X*q z7}lMWc?smO1^9%x`eYXV{QV;(eYF%wx+KUin8D%MjWi&Kv%n*=n1O*?7=#%aX3dcR v3W|8TIEHXsPfj?%^yB~k{{{jqVhjx4$J}?GPrJPrD9_;O>gTe~DWM4fsLv|z literal 0 HcmV?d00001 diff --git a/textures/techage_industriallamp1.png b/textures/techage_industriallamp1.png new file mode 100644 index 0000000000000000000000000000000000000000..8fc490000ef865bd111e772759c9bf12b9690e4a GIT binary patch literal 268 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvmUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIICs1s;*b3=G`DAk4@xYmNj^kUzjD#MLLW@Z5!STefXox_sG@qep80_6CA9 zmjw9*GdMiEkp|>cdb&7bcMR{d>N5 zliW+R4frnID%kbF#mKQ?eTq2ClPBgetw-79S8phOp=)=`Jyj^o@yuMUdkXKGA|==7 zSBAOtM}3#>7FqS{tKwXj!>(tp^PXO0s&2IM|BwFOdIzY7u_VYZn8D%M zjWiG^$=lt9p@UV{1IXbl@Q5sCVBi)8VMc~ob0mO*>?NMQuI!H)nK{HoMdy@=1BE7d zx;TbtoKH?*U=}N%&cv2-K+a0kHz8{Ua~FemhQ_Qe4->{|7d+TYj4y22F?|77faH|j z%Acq7NW?6^Q~h6_>)+n1K1mw9`@02pWLtJF6moSimGJFO6>#?C+_do2DV{Hk4%d|# z6CK&kDx|b~=A;D7ZFy6&I*sjeLJH$dw*_1#y0aWlv_+X4X=p2Qb4W2U6mpdbyxV9g Q2y`2Rr>mdKI;Vst08CzTTmS$7 literal 0 HcmV?d00001 diff --git a/textures/techage_industriallamp2.png b/textures/techage_industriallamp2.png new file mode 100644 index 0000000000000000000000000000000000000000..58eb44e91353a6c197f04f016c160ca8ad243795 GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIICs1s;*b3=G`DAk4@xYmNj^kSD+=#MLLW@cHv+mo8qkwz9I`@Bk>xz*rLG z7tG-B>_!@p6YA;W7$R{wIUyn8-~ay%%p3@03NRR*k literal 0 HcmV?d00001 diff --git a/textures/techage_industriallamp2_on.png b/textures/techage_industriallamp2_on.png new file mode 100644 index 0000000000000000000000000000000000000000..8d46b21f8d4f9073ac087fbfdab36c0116d3055b GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZz)@mUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIICs1s;*b3=G`DAk4@xYmNj+Fu*6o)hDy?|F<cM00FbtlAirP+hi5m^ zfE*i77sn8Z%gG4|2~k^DH8Qe1;5l~1gZ+}E#lcG#He9%{a$z9HF)fV)O0JWV_9*0B mUA0nxEx_<1&jw!(HUNS%G}U;vjb? zhIQv;UIID%0X`wFKAD9}mMwm8{oAA|6Zh@k)16Ql15#HK_hQX95>*vG`P|1!hdx7EA7c?GWWvq;^Skp6e>`v-RA;|?q1 T7YYDFj)B3`)z4*}Q$iB}xE`dH literal 0 HcmV?d00001 diff --git a/textures/techage_industriallamp_inv2.png b/textures/techage_industriallamp_inv2.png new file mode 100644 index 0000000000000000000000000000000000000000..18a975f3f802839157b2e55e8dabdecf63b4729c GIT binary patch literal 657 zcmV;C0&e|@P)Px#7*I@9MNDaN{`ai}1pzTGCDP52T39`fiD<5>d9*%J z`v3p{0d!JMQvg8b*k%9#010qNS#tmY3ljhU3ljkVnw%H_00H$$L_t(Y$L*9&Z`&{o zhK+V>uVt$^*F}nwYo}$)S;>~1EfnarcKZV=1KsZ*Ny)J-e*n7<1hQqB35nU-L`KW>gw5~RKXVTBo&AivuH+PDP8emXE9#h%0|!|!M?hZ!0+7q?1?Wpe0BQnqQ$i}y00+&z@{me^D*`}1 z`3CXjO9x<8l*K}2c!qm-0d62P3y(lPy-FQ{QwONyZ%b^vHX+`9`O*R+e#FeQ{iQ5D zJ`{H?5VI7HMjzZR0C@*6`{3W7FrAzW?Esm@>)C2%JN|I#o578CqP!7q+CN&i3hAotVM5badp@LP*WGm=6&F^kIkm0VxI1Y+4g|U z^LI9Zc`l{)(4T!PTodF0^Q1BD1Gmryaq?%i0+C$6H>@xQSz^%z+@+TsyAXq5(b$gx zaD#txkPqy+PE!a6NKy^m}n50yGQK65v|4L!D0QM1nz+w}HBO1c8Sr}y!5 rrL1_F+32`Qw{w21^*#GFdh=n3Y@DL{4Ubgac4Wvcxr_#5q4VH#M(>!MP|ku_QG`p**uBL&4qCHz2%`PaLRd zqo<2wh{pNaAVMhlrzw^VI*mf=3FDgLlOLtij0 zZB^FNY|nzf(@Z>fX9|nXn|rJz>S2~ty?xZHjmoaeZN#UiFHvXs!nJAj*}uP)f4i#c z^xnDqMwR$GGCWPK69GAEMn*PsguRdo)Is6c(V6w&Yp=t$1`}k`njxgN@xNA DIbwEC literal 0 HcmV?d00001 diff --git a/textures/techage_oil_animated.png b/textures/techage_oil_animated.png new file mode 100644 index 0000000000000000000000000000000000000000..643ee13ffa938f4829d862a6aa78599e54c32f97 GIT binary patch literal 2529 zcmWmGX*iVYAHeZvX3TC32FX$;WX+aj%{un&*ojWXXe18CDY6YZA-imeEGJuu$q};e z`xdfg&2Dt8A^iD2=ej=6_xHQ+clWy|%G^{BhvC5h0Dv>l*RcR6D*!+M6b#&AV-SJh z_-bx!MFJ-T1OY*yASeh51HnKrCK!|nEE9+c4uZqraIkO$2*HFvfJGodNH`J+7KuV4 zP+(CA6bdW~jY6QoqLFAcSTqKW#Gp|aaKRuk7!(ErE*LBbi^5{jSS+|;nL*4LW@fO= zIA$ykEDnpqfyJ?aSeRK@z_Q?3aCkfm9*<{b1+lWRf!NsDLF@!}c7|Sv@P7}xZ=|OK zM8f&?!2{Y$-<}EpQiA_|5Wjr&$KWN>*T95?T!iy*;yB%A0c8L{B^l^wTG_Q)+v1$R zRkD$^30GaO2s*Z0O=V?7lB4O?j{P1h_xsE9T+h!%e$>OPRUB#^%p&3g4*!Mq*gJoS z-`nw11nM`6*C7`7n3YvFzPMGsChDa7WwIt znaC;i?10hR%CBH0(=opH>)UxlDFI@~=eF}R@M%x8N(z3OkiEFKn3-pbj_9WjCwlwu23)JkrQG-hXy)twAIjD5}XpflpUlo5Q> z0Z66Ih1g#{tX+#yu(2QiHPbjou6peWQG}-jW!O#!?M~n?P(35}7K1Z}=jo2{1kP1q zymuWnht$r|lDxVUvEzv%Hh<$D3BI6ws@fs{KH>V=%fM*&!sG|-6RS!!2$v;)`@6Ez zR2D8<)Lyx(1C4o5r5$c6F|lA%{pp7kp!G@;a3}$W%Ow-zltp6!`5V1&svwPIc;LV+ zciXc@GTE|&xII$g8^DEyrt01)y*1blMNTGgcG;uW81JCrLt^){VZmb=k(RwX)d_b3 zg9^nxh`q2aYmdvYg-dC7DGiXqJ=t1B$Og}OVTE!wzI(T-=1Shzs=bh~;#o*jgu?2` z_lG}Ahimvs=_TGu^LN`1XG3bt>6t`YgiHa@}Ebmg)Aa1 zx1HQ1tr*h9@7-rG8qxmhN~e=yG^laNNnrdB49%l?BKyQ0`gX~1{Nd5Bt)RboBO|27 zZF{zE9mcvry83zPXXCRKSx@8z?rv?>9B@*I9zt=S>Pw0?Y!(I(0bQw_24hE3=Qd?D zPpLUJZYej6{R=+cW#edJdGkmPz~w!cM)P+hkf`ClQLZ=g&V?6xdw$9^lnU`L9L`F&*QYda{m<;dHj4-N7GH8 z)z_ryFK!{$cSU1LQr7?>{VZp=!5C(eY!{$kyG_)Hu&xwdpQ(J-`Tf$k`EFnBOE+v4 zFEo@X@g=USZ|M15qb#MAHkH4lCD{<8ss#ke(%z4vEEL2e)=ExzezLj6@c^#1sa;f5 z3^BH}zS`Ytz`>EsJ(^Yh`$0*&c+N^wil+un;}r_X6DoFY2*aAAfX$id_-S0gytY9Y z!IuzW=|uxR{8^V{81@>WMJVQK%2;_4n_D9xV?)ywh06RRYZsL%YmRGSJ)Ji($weo; zeUg5B6Z@EV|AME*L6ZqA053JyD@N~hy2xE21I@vrTKPqg#UFQ7%pm(An0Dx78#zeb z9B-I15grcF`)zQ>1ky6pY7JCcHFInQ2%q>!2gCgKU7=qQM^Ht`taX7NCBbmQ zidmdDtVmYp6TjS!Z5#ln6X8ao$Bsu{gvIvmsGFoL+@n+7rK=nn)h=^}q$aiP+%jWo zcMwr-#Rv6|4{VzhD8}`sL0k8XGg9v1N5mtejDsDpRbE(`KVe3A5+c9gn${dL3G9Hd-#W9SdAnzcn}!lS)omAr2b45>_? zwuC;bWySsl-<|;Gl6;lxP3sHvQtYz83ooKtV6$<*ztf66qvKRYBxZFW#e3i&`w2lY z|EZ4iR4gHY%qCOs9)YKLLAz$;#hISHEvW}g#y@XC9v|G)Aac^aysq7TLuTCHf!%0( z0;9E{MEq_M_FY5AadR;D&)k(1zB>X8D7L;oB(y9vQ%E2^5ht#+0YCs!GHWU^RLR?1w@Xhk9u*3GWKOXzwdR_?tg-z2R{kM1hbw;fmZ za=xd_Y^LS2g=dAT{CvOU^%%y)MB5}upc-D5xBAXL42vPrYu^f7mE35&r0K1tPm zkuMMf&V^3u*(!)EBLAwHqkZ`ZHbEK}e8mN$n;VQRy;u=c2w{#L!`#ufke z@~-Y;qDA+qx3h~}vQk>>Gf#UZlas}GxljqGCs4cd&eGAPn$0f+iHQE zzcLz^c&vV193jF5o#hU=Me0bJa*KLUmyT!ya#0%9d`i7E9rhpv188NBA(JHU>H2AB zTz*XXH%WsX7I!T_C)v4M-ot3@!X0TfLyp)>+}ff)wM#B4)Zyw+)SVN!>D_BDI=~+m Nz<^|`Q>t}0?EjLtLqh-n literal 0 HcmV?d00001 diff --git a/textures/techage_oil_inv.png b/textures/techage_oil_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..e3dbf85b01927095db8a850b1e133c9004249887 GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSoB=)|t_%$6K<5Ad|IeP;yA#M_ zED7=pW^j0RBMrn!@^*J&=wOxg04Xo``ZmF;&4DkV z<%M&d!>5&|HVjUT*@sj12`J8pE(lBG@o%`(R1&AUU+-b9e3AS$D=$TsjjTq>KCE9Z xKY3#v*7pCcm2Y3W?1$P5($;+$-