From 93d6cdbb89aa4208344125a339601be2e7ccc866 Mon Sep 17 00:00:00 2001 From: mrkubax10 Date: Tue, 6 May 2025 17:46:36 +0200 Subject: [PATCH] Implement Miner --- compatibility.lua | 2 + init.lua | 1 + machines/machine.lua | 7 + machines/miner.lua | 351 +++++++++++++++++++++++++++++++++++++++ tools/electric_drill.lua | 6 + 5 files changed, 367 insertions(+) create mode 100644 machines/miner.lua diff --git a/compatibility.lua b/compatibility.lua index 746fc37..ac6ae35 100644 --- a/compatibility.lua +++ b/compatibility.lua @@ -506,6 +506,7 @@ if industrialtest.mclAvailable then industrialtest.elementKeys.dryShrub="mcl_core:deadbush" industrialtest.elementKeys.cactus="mcl_core:cactus" industrialtest.elementKeys.gunpowder="mcl_mobitems:gunpowder" + industrialtest.elementKeys.chest="mcl_chests:chest_small" industrialtest.elementKeys.groupSapling="group:sapling" industrialtest.elementKeys.groupLeaves="group:leaves" industrialtest.elementKeys.stickyResin=(industrialtest.mods.mclRubber and "mcl_rubber:rubber_raw" or "industrialtest:sticky_resin") @@ -740,6 +741,7 @@ elseif industrialtest.mtgAvailable then industrialtest.elementKeys.dryShrub="default:dry_shrub" industrialtest.elementKeys.cactus="default:cactus" industrialtest.elementKeys.gunpowder="tnt:gunpowder" + industrialtest.elementKeys.chest="default:chest" industrialtest.elementKeys.groupSapling="group:sapling" industrialtest.elementKeys.groupLeaves="group:leaves" industrialtest.elementKeys.stickyResin="industrialtest:sticky_resin" diff --git a/init.lua b/init.lua index be6ca9b..6cbe525 100644 --- a/init.lua +++ b/init.lua @@ -56,6 +56,7 @@ dofile(modpath.."/machines/induction_furnace.lua") dofile(modpath.."/machines/iron_furnace.lua") dofile(modpath.."/machines/macerator.lua") dofile(modpath.."/machines/mass_fabricator.lua") +dofile(modpath.."/machines/miner.lua") dofile(modpath.."/machines/nuclear_reactor.lua") dofile(modpath.."/machines/power_storage.lua") dofile(modpath.."/machines/recycler.lua") diff --git a/machines/machine.lua b/machines/machine.lua index 410dfe4..aa1dbb0 100644 --- a/machines/machine.lua +++ b/machines/machine.lua @@ -32,6 +32,10 @@ function industrialtest.Machine.afterPlaceNode(self,pos,placer,itemstack,pointed -- dummy function end +function industrialtest.Machine.afterDigNode(self,pos,oldnode,oldmetadata,digger) + -- dummy function +end + function industrialtest.Machine.getFormspec(self,pos) local formspec if industrialtest.mtgAvailable then @@ -195,6 +199,9 @@ function industrialtest.Machine.createDefinitionTable(self) after_place_node=function(pos,placer,itemstack,pointed) self:afterPlaceNode(pos,placer,itemstack,pointed) end, + after_dig_node=function(pos,oldnode,oldmetadata,digger) + self:afterDigNode(pos,oldnode,oldmetadata,digger) + end, on_timer=function(pos,elapsed) return self:onTimer(pos,elapsed) end, diff --git a/machines/miner.lua b/machines/miner.lua new file mode 100644 index 0000000..f06439a --- /dev/null +++ b/machines/miner.lua @@ -0,0 +1,351 @@ +-- IndustrialTest +-- Copyright (C) 2025 mrkubax10 + +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. + +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. + +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +local S=minetest.get_translator("industrialtest") + +local function destructMiningPipe(pos,player) + local count=0 + local originalPos=table.copy(pos) + local node=minetest.get_node(pos) + while node.name=="industrialtest:mining_pipe" do + count=count+1 + pos.y=pos.y-1 + node=minetest.get_node(pos) + if node.name=="ignore" then + minetest.load_area(pos) + node=minetest.get_node(pos) + end + end + local endPos=table.copy(pos) + + local manip=minetest.get_voxel_manip() + local minp,maxp=manip:read_from_map(pos,originalPos) + local data=manip:get_data() + local area=VoxelArea(minp,maxp) + pos=table.copy(originalPos) + while pos.y>endPos.y do + data[area:index(pos.x,pos.y,pos.z)]=minetest.CONTENT_AIR + pos.y=pos.y-1 + end + manip:set_data(data) + manip:write_to_map() + + if player then + local itemstack=ItemStack("industrialtest:mining_pipe "..tostring(count)) + if industrialtest.mtgAvailable then + local inv=player:get_inventory() + local leftover=inv:add_item("main",itemstack) + if not leftover:is_empty() then + minetest.add_item(player:get_pos(),leftover) + end + elseif industrialtest.mclAvailable then + minetest.add_item(originalPos,itemstack) + end + end +end + +local function miningPipeUpdateMiner(pos) + local meta=minetest.get_meta(pos) + if meta:contains("miner") then + local minerPos=minetest.deserialize(meta:get_string("miner")) + local minerMeta=minetest.get_meta(minerPos) + minerMeta:set_int("level",pos.y) + end +end + +local definition={ + description=S("Mining Pipe"), + tiles={"industrialtest_mining_pipe.png"}, + paramtype="light", + sunlight_propagates=true, + drawtype="nodebox", + node_box={ + type="fixed", + fixed={ + -0.25, + -0.5, + -0.25, + 0.25, + 0.5, + 0.25 + } + }, + on_destruct=function(pos) + miningPipeUpdateMiner(pos) + destructMiningPipe(pos,nil) + end, + on_dig=function(pos,node,digger) + miningPipeUpdateMiner(pos) + destructMiningPipe(pos,digger) + end +} +if industrialtest.mtgAvailable then + definition.groups={ + cracky=3, + oddly_breakable_by_hand=1 + } + definition.sounds=default.node_sound_metal_defaults() +elseif industrialtest.mclAvailable then + definition.groups={ + pickaxey=1, + handy=1 + } + definition.sounds=mcl_sounds.node_sound_metal_defaults() + definition._mcl_blast_resistance=1 + definition._mcl_hardness=1 +end +minetest.register_node("industrialtest:mining_pipe",definition) + +minetest.register_craft({ + type="shaped", + output="industrialtest:mining_pipe 8", + recipe={ + {"industrialtest:refined_iron_ingot","","industrialtest:refined_iron_ingot"}, + {"industrialtest:refined_iron_ingot","","industrialtest:refined_iron_ingot"}, + {"industrialtest:refined_iron_ingot",industrialtest.elementKeys.treetap,"industrialtest:refined_iron_ingot"} + } +}) + +industrialtest.Miner=table.copy(industrialtest.ElectricMachine) +industrialtest.internal.unpackTableInto(industrialtest.Miner,{ + name="industrialtest:miner", + description=S("Miner"), + tiles={ + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png^industrialtest_miner_front.png" + }, + sounds="metal", + storageLists={ + "drill", + "src", + "scanner", + "dst", + "powerStorage", + "upgrades" + }, + powerLists={ + { + list="powerStorage", + direction="i" + } + }, + requiresWrench=true, + facedir=true, + flow=industrialtest.api.lvPowerFlow, + capacity=5000, + ioConfig="iiiiii", + hasPowerInput=true, + _opPower=1000 +}) + +function industrialtest.Miner.onConstruct(self,pos) + local meta=minetest.get_meta(pos) + local inv=meta:get_inventory() + inv:set_size("drill",1) + inv:set_size("src",1) + inv:set_size("scanner",1) + inv:set_size("dst",15) + inv:set_size("powerStorage",1) + inv:set_size("upgrades",1) + meta:set_int("level",pos.y-1) + industrialtest.ElectricMachine.onConstruct(self,pos) +end + +function industrialtest.Miner.onDestruct(self,pos) + destructMiningPipe(vector.new(pos.x,pos.y-1,pos.z),nil) + industrialtest.ElectricMachine.onDestruct(self,pos) +end + +function industrialtest.Miner.afterDigNode(self,pos,oldnode,oldmetadata,digger) + destructMiningPipe(vector.new(pos.x,pos.y-1,pos.z),digger) +end + +function industrialtest.Miner.getFormspec(self,pos) + local parentFormspec=industrialtest.ElectricMachine.getFormspec(self,pos) + local meta=minetest.get_meta(pos) + local powerPercent=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")*100 + local formspec={ + "label[0.7,1.2;"..S("Drill").."]", + "list[context;drill;0.7,1.5;1,1]", + industrialtest.internal.getItemSlotBg(0.7,1.5,1,1), + "label[0.7,2.8;"..S("Pipe").."]", + "list[context;src;0.7,3.1;1,1]", + industrialtest.internal.getItemSlotBg(0.7,3.1,1,1), + "label[0.7,4.4;"..S("Scanner").."]", + "list[context;scanner;0.7,4.7;1,1]", + industrialtest.internal.getItemSlotBg(0.7,4.7,1,1), + "list[context;dst;2.28,1.9;5,3]", + industrialtest.internal.getItemSlotBg(2.28,1.9,5,3), + "list[context;upgrades;9.1,1.2;1,1]", + industrialtest.internal.getItemSlotBg(9.1,1.2,1,1), + (powerPercent>0 and "image[9.1,2.29;1,1;industrialtest_gui_electricity_bg.png^[lowpart:"..powerPercent..":industrialtest_gui_electricity_fg.png]" + or "image[9.1,2.29;1,1;industrialtest_gui_electricity_bg.png]"), + "list[context;powerStorage;9.1,3.5;1,1]", + industrialtest.internal.getItemSlotBg(9.1,3.5,1,1), + } + return parentFormspec..table.concat(formspec,"") +end + +function industrialtest.Miner.canUpdate(self,pos) + local meta=minetest.get_meta(pos) + local inv=meta:get_inventory() + local drillSlot=inv:get_stack("drill",1) + local srcSlot=inv:get_stack("src",1) + local level=meta:get_int("level") + return meta:get_int("industrialtest.powerAmount")>=self._opPower and not drillSlot:is_empty() and not srcSlot:is_empty() and + self:canContinue(pos,level) +end + +function industrialtest.Miner.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) + local meta=minetest.get_meta(pos) + local inv=meta:get_inventory() + local itemstack=inv:get_stack(fromList,fromIndex) + if toList=="drill" then + return self.allowDrillPut(itemstack) and count or 0 + end + if toList=="src" then + return itemstack:get_name()=="industrialtest:mining_pipe" and count or 0 + end + if toList=="scanner" then + return self.allowScannerPut(itemstack) and 1 or 0 + end + if toList=="dst" then + return 0 + end + return industrialtest.ElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) +end + +function industrialtest.Miner.allowMetadataInventoryPut(self,pos,listname,index,itemstack,player) + if listname=="drill" then + return self.allowDrillPut(itemstack) and itemstack:get_count() or 0 + end + if listname=="src" then + return itemstack:get_name()=="industrialtest:mining_pipe" and itemstack:get_count() or 0 + end + if listname=="scanner" then + return self.allowScannerPut(itemstack) and 1 or 0 + end + if listname=="dst" then + return 0 + end + return industrialtest.ElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player) +end + +function industrialtest.Miner.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) + self:onInventoryPut(pos,toList) + industrialtest.ElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) +end + +function industrialtest.Miner.onMetadataInventoryPut(self,pos,listname,index,stack) + self:onInventoryPut(pos,listname) + industrialtest.ElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack) +end + +function industrialtest.Miner.onMetadataInventoryTake(self,pos,listname,index,stack) + if listname=="dst" then + self:triggerIfNeeded(pos) + end +end + +function industrialtest.Miner.update(self,pos,elapsed,meta,inv) + if not self:canUpdate(pos) then + return false,false + end + + local level=meta:get_int("level") + if not self:canContinue(pos,level) then + return false,false + end + + local srcSlot=inv:get_stack("src",1) + srcSlot:take_item(1) + inv:set_stack("src",1,srcSlot) + local targetPos=vector.new(pos.x,level,pos.z) + local drop=self.getNodeDrop(targetPos) + self.placeMiningPipe(pos,targetPos) + inv:add_item("dst",drop) + meta:set_int("level",level-1) + industrialtest.api.addPower(meta,-self._opPower) + + return true,true +end + +function industrialtest.Miner.onInventoryPut(self,pos,listname) + if listname=="drill" or listname=="src" then + self:triggerIfNeeded(pos) + end +end + +function industrialtest.Miner.allowDrillPut(itemstack) + local def=itemstack:get_definition() + return def and def.groups and def.groups._industrialtest_miningDrill +end + +function industrialtest.Miner.allowScannerPut(itemstack) + local def=itemstack:get_definition() + return def and def.groups and def.groups._industrialtest_scanner +end + +function industrialtest.Miner.canContinue(self,pos,level) + local meta=minetest.get_meta(pos) + local inv=meta:get_inventory() + local targetPos=vector.new(pos.x,level,pos.z) + local targetNode=minetest.get_node(targetPos) + if targetNode.name=="ignore" then + minetest.load_area(targetPos) + targetNode=minetest.get_node(targetPos) + if targetNode.name=="ignore" then + return false + end + end + + local def=minetest.registered_nodes[targetNode.name] + local drop=self.getNodeDrop(vector.new(pos.x,level,pos.z)) + return not (def and def.groups and def.groups.unbreakable) and inv:room_for_item("dst",drop) +end + +function industrialtest.Miner.getNodeDrop(pos) + local node=minetest.get_node(pos) + local def=minetest.registered_nodes[node.name] + if not def.pointable then + return ItemStack() + end + return ItemStack((def and def.drop and def.drop~="") and def.drop or node.name) +end + +function industrialtest.Miner.placeMiningPipe(minerPos,pos) + minetest.add_node(pos,{ + name="industrialtest:mining_pipe" + }) + local meta=minetest.get_meta(pos) + meta:set_string("miner",minetest.serialize(minerPos)) +end + +industrialtest.Miner:register() + +minetest.register_craft({ + type="shaped", + output="industrialtest:miner", + recipe={ + {"",industrialtest.elementKeys.chest,""}, + {"industrialtest:electronic_circuit","industrialtest:machine_block","industrialtest:electronic_circuit"}, + {"","industrialtest:mining_pipe",""} + } +}) diff --git a/tools/electric_drill.lua b/tools/electric_drill.lua index a723d8e..0b3d566 100644 --- a/tools/electric_drill.lua +++ b/tools/electric_drill.lua @@ -23,6 +23,12 @@ industrialtest.internal.unpackTableInto(industrialtest.ElectricDrillBase,{ } }) +function industrialtest.ElectricDrillBase.createDefinitionTable(self) + local def=industrialtest.ActivatedElectricTool.createDefinitionTable(self) + def.groups._industrialtest_miningDrill=1 + return def +end + function industrialtest.ElectricDrillBase.getOpPower(self,itemstack) return 50 end