Compare commits

...

119 Commits

Author SHA1 Message Date
17a9cab691 Release IndustrialTest 2.0.0 (stable, release) 2025-05-14 23:23:30 +02:00
322655f483 Implement cable melting 2025-05-12 21:44:33 +02:00
2dae1d931d Re-add electrocution by uninsulated cables 2025-05-11 18:34:25 +02:00
ce0a5ad2e6 Add industrialtest.api.getFlowingCurrent API function 2025-05-11 18:34:12 +02:00
c8e506be53 LV Solar Array now outputs LV 2025-05-09 20:13:08 +02:00
5161f70232 Add Miner front texture 2025-05-09 19:37:31 +02:00
969744f242 Use mcl_tooltips for handling additional information for items if necessary 2025-05-09 19:02:00 +02:00
c58aeb308b Update texture sources list 2025-05-09 14:26:24 +02:00
16c8bed915 Add OV Scanner texture 2025-05-09 14:23:30 +02:00
a6cb0d4ed1 Add OD Scanner texture 2025-05-09 14:23:23 +02:00
50565ca604 Implement scanners and add way to use them in Miner 2025-05-08 22:25:32 +02:00
ea422c5999 Some Miner tweaks 2025-05-07 18:51:00 +02:00
65e0304c9e Add Mining Pipe texture 2025-05-06 18:00:07 +02:00
93d6cdbb89 Implement Miner 2025-05-06 18:00:00 +02:00
03ff0ac8ce Add missing } in uu_matter_crafts.lua 2025-05-04 17:23:35 +02:00
7391ad34f3 Add few more crafts involving UU-Matter 2025-04-30 13:36:09 +02:00
4d544099b1 Refactor utils 2025-04-29 12:34:05 +02:00
52f5a5c672 Refactor cables 2025-04-29 12:14:54 +02:00
47b85df93c Refactor upgrades 2025-04-29 11:21:14 +02:00
43484defad Update Hydrated Coal Dust texture to match regular dust 2025-04-29 10:18:20 +02:00
9b57098fca Move configuration to in-game settings 2025-04-29 10:14:20 +02:00
63960f3de1 Refactor item fluid storage 2025-04-28 13:36:17 +02:00
84ff508056 Refactor item power storage 2025-04-28 13:10:41 +02:00
62246bf91b Make sure that pointed thing is node when using treetap 2025-04-28 12:53:19 +02:00
8d48b3f9f5 Refactor wrench 2025-04-28 12:53:03 +02:00
089550cc28 Make sure to define on_place callback for treetaps 2025-04-25 22:18:16 +02:00
462e731bb7 Fix bone meal usage on rubber tree saplings in mcl2 2025-04-25 22:17:40 +02:00
2c63498d78 Remove outdated TEXTURES_TODO.md file 2025-04-25 10:51:57 +02:00
5898cc4e1c Merge pull request 'add sound at jetpack' (#29) from Kindaglia/industrialtest:sound into master 2025-04-25 10:48:46 +02:00
e41dfb3344 Remove leftover testing messages 2025-04-25 10:43:21 +02:00
230c9803ea Refactor Quantum Suit 2025-04-25 10:42:33 +02:00
Kindaglia
f651e407f7 fix naming 2025-04-25 10:12:45 +02:00
Kindaglia
f5f27ef999 rename and fix sound jetpack 2025-04-25 00:14:45 +02:00
Kindaglia
68abb4d08e add sound jetpack 2025-04-24 21:12:15 +02:00
Kindaglia
f1d8d5060c add sound jetpack ogg 2025-04-24 20:52:55 +02:00
5b32382422 Refactor Static Boots 2025-04-24 13:46:45 +02:00
30c67390b2 Refactor Solar Helmet 2025-04-23 14:22:18 +02:00
e34c1eba66 Refactor Nano Suit 2025-04-23 13:11:25 +02:00
6e1d0b5229 Refactor Mining Laser 2025-04-19 20:18:02 +02:00
000cff6940 Refactor jetpacks 2025-04-17 13:49:06 +02:00
b383231c40 Refactor electric sabers 2025-04-15 22:47:44 +02:00
6f864eca78 Refactor electric hoes 2025-04-14 16:32:58 +02:00
9cb5748b73 Refactor electric drills 2025-04-14 14:48:42 +02:00
b108ce7c6a Refactor electric chainsaws 2025-04-10 22:47:47 +02:00
dfdce73376 Refactor batpacks 2025-04-08 21:28:28 +02:00
6147074e05 Refactor treetaps 2025-04-06 22:08:43 +02:00
ae123446ad Move some common tool functionality to separate files for further usage 2025-04-06 22:07:38 +02:00
25680ace72 Fix issue while moving item in Canning Machine 2025-04-05 23:03:17 +02:00
c57efcdd5c Re-add Pipeworks compatibility 2025-04-05 23:03:05 +02:00
acdbad46c6 Re-add Mesecons compatibility 2025-04-05 18:06:48 +02:00
8e4fdb217a Re-add Logistica compatibility 2025-04-05 16:18:37 +02:00
656e33737d Some random clean ups and fixes 2025-04-04 22:58:24 +02:00
1343aa2c23 Refactor Wind Mill 2025-04-04 20:34:11 +02:00
0ac1dd0e49 Refactor solar panels 2025-04-04 19:57:46 +02:00
329dd0e293 Re-add remaining functionality to industrialtest.api.createNetworkMap 2025-04-03 17:40:27 +02:00
30d5ebffe5 Refactor transformers 2025-04-03 17:34:40 +02:00
fd772f3c55 Rewrite industrialtest.api.createNetworkMap and few other network related features 2025-04-02 23:02:26 +02:00
b18b6e5a32 Some various fixes and changes in machine.lua and electric_machine.lua 2025-03-31 11:54:47 +02:00
38b08bcb0d Refactor Tool Workshop 2025-03-30 21:19:00 +02:00
b6ce12a668 Fix machine side IO lookups 2025-03-29 14:25:03 +01:00
69aadeae71 Refactor power storage 2025-03-27 22:54:31 +01:00
6c9c69a308 Prevent using items partially used by Rotary Macerator 2025-03-27 22:18:42 +01:00
cb43a7ab76 Refactor Rotary Macerator 2025-03-25 21:24:29 +01:00
bbd9e2ece0 Refactor Nuclear Reactor 2025-03-19 22:15:18 +01:00
b3d08d965c Add few callback methods to Machine 2025-03-19 22:14:52 +01:00
29662f1821 Remove duplicated tiles entry in some machines 2025-03-17 19:51:12 +01:00
80cbc12a8a Refactor Induction Furnace 2025-03-17 18:52:13 +01:00
4c6b4b9df0 Fix machines not triggered when item with power storage is placed in inventory 2025-03-16 20:20:54 +01:00
3a1cfad7d4 Add workaround for NodeTimerRef.is_started not returning correct value 2025-03-16 11:38:43 +01:00
d3c9d3ed7a Refactor fluid generators 2025-03-16 11:37:44 +01:00
abfb829cea Use Machine.triggerIfNeeded to request power 2025-03-16 11:35:53 +01:00
8e30412515 Refactor Mass Fabricator 2025-03-11 22:19:46 +01:00
d247060c2e Refactor Recycler 2025-03-11 21:25:01 +01:00
ef88c5cd6b Refactor Macerator 2025-03-11 19:55:29 +01:00
5e99610747 Refactor Extractor 2025-03-11 19:45:56 +01:00
9a49e49fe3 Refactor Electric Furnace 2025-03-11 19:40:31 +01:00
5ddeeed36f Refactor Cable Former 2025-03-11 19:12:57 +01:00
c379b133dc Update formspec after item is taken when it's actually needed 2025-03-11 18:55:11 +01:00
70dacf9a8c Make sure to properly distribute available power across all endpoints 2025-03-10 11:55:48 +01:00
4698266b33 Don't take fuel input in Generator.shouldActivate 2025-03-10 11:46:09 +01:00
165450f857 Refactor Compressor 2025-03-10 11:16:36 +01:00
18a1cbc983 Refactor base for simple electric item processors 2025-03-10 11:15:31 +01:00
ab7d011afd Remove redundant return value from ActivatedMachine.activeUpdate 2025-03-10 11:06:38 +01:00
371ef36ce3 Refactor Chargepad 2025-03-03 11:45:36 +01:00
8f529ad6c3 Fix few oversights and bring back some missing features 2025-03-03 11:44:18 +01:00
09a0d9c855 Use appropriate item power exchange direction 2025-01-20 22:21:06 +01:00
fd45e58e9c Change MineClone2 to VoxeLibre in README.md 2025-01-08 22:50:53 +01:00
ca99ab38b5 Refactor Canning Machine 2025-01-08 22:47:11 +01:00
6934a8b342 Fix some oversights 2025-01-08 22:46:16 +01:00
752fe4f192 Optimize electric network operations a little 2025-01-08 22:45:12 +01:00
6e2a3c22cf Create fluid utility functions in API 2025-01-08 22:43:30 +01:00
c50871a96b Change Machine.storageSlots to Machine.storageLists 2024-10-25 12:42:42 +02:00
78637a4759 Refactor Generator 2024-10-25 12:42:04 +02:00
83ee6fb4c8 Fixes in ActivatedElectricMachine and ElectricMachine 2024-10-25 12:40:27 +02:00
1f6f711b64 Forgot to add fuel slot to storageSlots 2024-10-24 16:36:38 +02:00
6befcdeb01 Refactor Iron Furnace 2024-10-24 16:33:34 +02:00
d799b10242 Some fixes in Machine and ActivatedMachine 2024-10-24 16:32:57 +02:00
442d3a42b1 Change Activated{Electric}Machine.before{Activation|Deactivation} to Activated{Electric}Machine.after{Activation|Deactivation} 2024-10-24 16:30:20 +02:00
fd3df487e5 Implement util function for merging 2 tables 2024-10-24 16:28:18 +02:00
52aea868a5 Begin implementing more OOP-like design 2024-10-15 16:28:59 +02:00
db1d7fe820 Add Logistica to optional dependencies in README.md 2024-09-16 10:27:06 +02:00
959c5ac6b8 Remove debug log message 2024-09-16 10:25:36 +02:00
19c97f0173 Implement Logistica compatibility 2024-09-14 17:35:57 +02:00
3419fcb660 Introduce tag system for further usage 2024-09-11 15:29:03 +02:00
636c0cda64 Remove unnecessary constant 2024-09-11 15:04:36 +02:00
ce4e1b52ba Some leftover API files fixes 2024-09-08 22:57:08 +02:00
07ea380ed7 Extract registration API functions to separate file 2024-09-08 22:53:09 +02:00
e18789451c Extract network API functions to separate file 2024-09-08 22:46:41 +02:00
e2d91cd8c5 Extract tool API functions to separate file 2024-09-08 22:41:37 +02:00
0363a2ba26 Extract fluid API functions to separate file 2024-09-08 22:36:33 +02:00
cb41e76742 Extract side API functions to separate file 2024-09-08 22:31:26 +02:00
9436c7033b Extract power API functions to separate file 2024-09-08 22:27:36 +02:00
2a607bedfe Release IndustrialTest 1.1.0 (stable, release) 2024-06-12 10:57:50 +02:00
4ac7210f40 Don't try to remove node from invalid network master 2024-05-13 19:44:16 +02:00
5b5816a65c Make only higher power flow destroy transformer
Fixes #24
2024-05-13 19:03:25 +02:00
36549e9a49 Fix electric tools breaking
Fixes #13
2024-05-12 20:36:31 +02:00
bea76ecc62 Merge pull request #28 from HandfulOfFrogs/industrialtest:feat/enchantability into master 2024-05-12 19:52:31 +02:00
fd569985da Merge pull request #27 from HandfulOfFrogs/industrialtest:fix/bronze-crafting into master 2024-05-12 19:51:28 +02:00
67f503758f feat: enchantability for bronze armor and weapons 2024-05-12 10:59:12 +03:00
88 changed files with 7378 additions and 5281 deletions

View File

@ -9,12 +9,13 @@ Currently IndustrialTest supports following games:
## Additional dependencies
- Minetest Game
- [3D Armor](https://content.minetest.net/packages/stu/3d_armor)
- MineClone2
- VoxeLibre
- none
## Optional dependencies
- [Rubber Addon for MineClone](https://content.minetest.net/packages/biochemist/mcl_rubber)
- [Pipeworks](https://content.minetest.net/packages/VanessaE/pipeworks)
- [Logistica](https://content.minetest.net/packages/ZenonSeth/logistica)
- [Mesecons](https://content.minetest.net/packages/Jeija/mesecons)
## Contributors

View File

@ -1,4 +0,0 @@
# List of textures that still have to be done
- bronze toolset for MCL
- bronze nugget for MCL
- advanced electronic circuit

900
api.lua
View File

@ -1,900 +0,0 @@
-- IndustrialTest
-- Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.api={}
industrialtest.api.maceratorRecipes={}
industrialtest.api.compressorRecipes={}
industrialtest.api.extractorRecipes={}
industrialtest.api.cableFormerRecipes={}
industrialtest.api.geothermalGeneratorFuels={}
industrialtest.api.waterMillFuels={}
industrialtest.api.rotaryMaceratorModifiers={}
industrialtest.api.storageCells={}
industrialtest.api.lvPowerFlow=600
industrialtest.api.mvPowerFlow=2400
industrialtest.api.hvPowerFlow=10200
industrialtest.api.evPowerFlow=40800
industrialtest.api.ivPowerFlow=163800
industrialtest.internal.clamp=function(num,min,max)
return math.max(math.min(num,max),min)
end
-- \brief Adds power storage to metadata
-- \param capacity How much EU item/node can store
-- \param flow How much EU can flow in or out item/node per industrialtest.updateDelay
-- \param ioConfig Input/Output configuration in following side order: -X, +X, -Y, +Y, -Z, +Z
-- a - bidirectional, i - input, o - output
-- \returns nil
industrialtest.api.addPowerStorage=function(meta,capacity,flow,ioConfig)
meta:set_int("industrialtest.powerCapacity",capacity)
meta:set_int("industrialtest.powerFlow",flow)
meta:set_int("industrialtest.powerAmount",0)
meta:set_string("industrialtest.ioConfig",ioConfig)
end
-- \brief Takes rotated node and side and outputs normalized side that can be used for ioConfig lookups
-- \param pos Vector with node position
-- \param side Node side. See industrialtest.api.addPowerStorage for possible values
-- \returns Normalized side or in case of failure side argument back
industrialtest.api.normalizeSide=function(pos,side)
local node=minetest.get_node(pos)
-- FIXME: improve code quality there
local translation={
[0]={
1,2,3,4,5,6
},
[1]={
5,6,3,4,2,1
},
[2]={
2,1,3,4,6,5
},
[3]={
6,5,3,4,1,2
}
}
if node.param2>3 then
return side
end
return translation[node.param2][side]
end
-- \brief Checks if metadata contains power storage
-- \param meta MetaDataRef which should be checked
-- \returns true if metadata contains power storage, false otherwise
industrialtest.api.hasPowerStorage=function(meta)
local values={"industrialtest.powerCapacity","industrialtest.powerFlow","industrialtest.powerAmount","industrialtest.ioConfig"}
for _,value in ipairs(values) do
if not meta:contains(value) then
return false
end
end
return true
end
-- \brief Updates itemstack description to show current power storage information, additionally updates item wear bar.
-- Function doesn't check if itemstack contains power storage so you should be sure that it does before calling this function
-- \param itemstack ItemStack which should be updated
-- \returns nil
industrialtest.api.updateItemPowerText=function(itemstack)
local meta=itemstack:get_meta()
local def=minetest.registered_tools[itemstack:get_name()]
local desc=meta:contains("industrialtest.descriptionOverride") and meta:get_string("industrialtest.descriptionOverride") or def.description
meta:set_string("description",S("@1\n@2 / @3 EU",desc,meta:get_int("industrialtest.powerAmount"),meta:get_int("industrialtest.powerCapacity")))
itemstack:set_wear(65535-meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")*65534)
end
-- \brief Adds power storage to item depending on it's definition
-- \param itemstack ItemStack to which item storage should be added
-- \returns true if power storage was successfully added, false otherwise
industrialtest.api.preparePowerStorageItem=function(itemstack)
local meta=itemstack:get_meta()
local def=minetest.registered_tools[itemstack:get_name()]
if industrialtest.api.hasPowerStorage(meta) or not def or not def._industrialtest_powerStorage or not def._industrialtest_powerCapacity or not def._industrialtest_powerFlow then
return false
end
industrialtest.api.addPowerStorage(meta,def._industrialtest_powerCapacity,def._industrialtest_powerFlow,"n/a")
industrialtest.api.updateItemPowerText(itemstack)
return true
end
-- \brief Sets uses metadata value depending on item's definition
-- \param itemstack ItemStack which should be altered
-- \returns true if value was successfully added, false otherwise
industrialtest.api.prepareToolItem=function(itemstack)
local def=minetest.registered_tools[itemstack:get_name()]
if not def then
return false
end
if def._industrialtest_tool and def.tool_capabilities and def.tool_capabilities.uses then
local meta=itemstack:get_meta()
meta:set_int("industrialtest.uses",def.tool_capabilities.uses)
return true
elseif def.groups and def.groups._industrialtest_emptyOnConstruct and itemstack:get_wear()==0 then
itemstack:set_wear(65534)
return true
end
return false
end
-- \brief Adds wear to item after it's use
-- \param itemstack ItemStack to which wear should be added
-- \returns nil
industrialtest.api.afterToolUse=function(itemstack)
local meta=itemstack:get_meta()
local def=minetest.registered_tools[itemstack:get_name()]
if not def or not def._industrialtest_tool or not def.tool_capabilities or not def.tool_capabilities.uses then
return
end
if not meta:contains("industrialtest.uses") then
industrialtest.prepareToolItem(itemstack)
end
local uses=meta:get_int("industrialtest.uses")-1
if uses==0 then
itemstack:set_count(0)
minetest.sound_play({name="default_tool_breaks"},{
gain=1,
fade=0,
pitch=1
},true)
return
end
meta:set_int("industrialtest.uses",uses)
itemstack:set_wear(65535-uses/def.tool_capabilities.uses*65535)
end
-- \brief Check if itemstack contains fluid storage
-- \param itemstack ItemStack
-- \returns bool
industrialtest.api.itemHasFluidStorage=function(itemstack)
local values={"industrialtest.fluidAmount","industrialtest.fluidCapacity"}
local meta=itemstack:get_meta()
for _,value in ipairs(values) do
if not meta:contains(value) then
return false
end
end
return true
end
-- \brief Updates itemstack description and wear depending on contained fluid
-- \param itemstack ItemStack
-- \returns nil
industrialtest.api.updateItemFluidText=function(itemstack)
local meta=itemstack:get_meta()
local def=itemstack:get_definition()
meta:set_string("description",S("@1\n@2 / @3 mB",def.description,meta:get_int("industrialtest.fluidAmount"),meta:get_int("industrialtest.fluidCapacity")))
itemstack:set_wear(65535-meta:get_int("industrialtest.fluidAmount")/meta:get_int("industrialtest.fluidCapacity")*65534)
end
-- \brief Prepares itemstack containing fluid storage
-- \param itemstack ItemStack
-- \returns bool
industrialtest.api.prepareFluidStorageItem=function(itemstack)
local meta=itemstack:get_meta()
local def=itemstack:get_definition()
if industrialtest.api.itemHasFluidStorage(itemstack) or not def.groups or not def.groups._industrialtest_fluidStorage or not def._industrialtest_fluidCapacity then
return false
end
meta:set_int("industrialtest.fluidAmount",0)
meta:set_int("industrialtest.fluidCapacity",def._industrialtest_fluidCapacity)
industrialtest.api.updateItemFluidText(itemstack)
return true
end
-- \brief Adds fluid amount to item fluid storage
-- \param itemstack ItemStack
-- \param amount number
-- \returns number
industrialtest.api.addFluidToItem=function(itemstack,amount)
local meta=itemstack:get_meta()
if not industrialtest.api.itemHasFluidStorage(itemstack) then
return 0
end
local fluidAmount=meta:get_int("industrialtest.fluidAmount")
local fluidCapacity=meta:get_int("industrialtest.fluidCapacity")
local prevFluidAmount=fluidAmount
fluidAmount=industrialtest.internal.clamp(fluidAmount+amount,0,fluidCapacity)
meta:set_int("industrialtest.fluidAmount",fluidAmount)
industrialtest.api.updateItemFluidText(itemstack)
return fluidAmount-prevFluidAmount
end
-- \brief Adds fluid to destination itemstack while subtracting it from source itemstack's metadata
-- \param srcItemstack ItemStack
-- \param itemstack ItemStack
-- \param amount number
-- \returns number
industrialtest.api.transferFluidToItem=function(srcItemstack,itemstack,amount)
local meta=srcItemstack:get_meta()
local flow=math.min(meta:get_int("industrialtest.fluidAmount"),amount)
if flow==0 then
return 0
end
local actualFlow=industrialtest.api.addFluidToItem(itemstack,flow)
meta:set_int("industrialtest.fluidAmount",meta:get_int("industrialtest.fluidAmount")-actualFlow)
industrialtest.api.updateItemFluidText(srcItemstack)
return actualFlow
end
-- \brief Checks if power storage is fully charged
-- \param meta MetaDataRef which should be checked
-- \returns true if power storage is fully charged, false otherwise
industrialtest.api.isFullyCharged=function(meta)
return meta:get_int("industrialtest.powerAmount")>=meta:get_int("industrialtest.powerCapacity")
end
-- \brief Adds power to power storage. Function doesn't check if meta contains power storage so you must be sure that it does.
-- \param meta MetaDataRef to which power should be added
-- \param amount Amount of power to add
-- \returns How much of power was actually added
industrialtest.api.addPower=function(meta,amount)
local powerAmount=meta:get_int("industrialtest.powerAmount")
local powerCapacity=meta:get_int("industrialtest.powerCapacity")
local prevPowerAmount=powerAmount
powerAmount=industrialtest.internal.clamp(powerAmount+amount,0,powerCapacity)
meta:set_int("industrialtest.powerAmount",powerAmount)
return powerAmount-prevPowerAmount
end
-- \brief Adds power to itemstack. Function checks if itemstack has power storage.
-- \param itemstack ItemStack to which add power
-- \param amount How much power to add
-- \returns Amount of power added
industrialtest.api.addPowerToItem=function(itemstack,amount)
local meta=itemstack:get_meta()
if not industrialtest.api.hasPowerStorage(meta) then
return 0
end
local added=industrialtest.api.addPower(meta,amount)
industrialtest.api.updateItemPowerText(itemstack)
return added
end
-- \brief Adds power to destination metadata while subtracting it from source metadata
-- \Param srcMeta MetaDataRef from which take power
-- \param destMeta MetaDataRef to which add power
-- \returns How much of power was actually transferred
industrialtest.api.transferPower=function(srcMeta,destMeta,amount)
local currentFlow=math.min(srcMeta:get_int("industrialtest.powerAmount"),amount)
if currentFlow==0 then
return 0
end
local actualFlow=industrialtest.api.addPower(destMeta,currentFlow)
srcMeta:set_int("industrialtest.powerAmount",srcMeta:get_int("industrialtest.powerAmount")-actualFlow)
return actualFlow
end
-- \brief Adds power to destination itemstack while subtracting it from source metadata
-- \param srcMeta MetaDataRef from which take power
-- \param itemstack ItemStack to which add power
-- \param amount number
-- \returns How much of power was actually transferred
industrialtest.api.transferPowerToItem=function(srcMeta,itemstack,amount)
local currentFlow=math.min(srcMeta:get_int("industrialtest.powerAmount"),amount)
if currentFlow==0 then
return 0
end
local actualFlow=industrialtest.api.addPowerToItem(itemstack,currentFlow)
srcMeta:set_int("industrialtest.powerAmount",srcMeta:get_int("industrialtest.powerAmount")-actualFlow)
return actualFlow
end
-- \brief Adds power to destination metadata while subtracting it from source itemstack
-- \param srcItemstack ItemStack from which subtract power
-- \param meta MetaDataRef to which add power
-- \param amount How much power should be transferred
-- \returns How much of power was actually transferred
industrialtest.api.transferPowerFromItem=function(srcItemstack,meta,amount)
local srcMeta=srcItemstack:get_meta()
local currentFlow=math.min(srcMeta:get_int("industrialtest.powerAmount"),amount)
if currentFlow==0 then
return 0
end
local actualFlow=industrialtest.api.addPower(meta,currentFlow)
industrialtest.api.addPowerToItem(srcItemstack,-actualFlow)
return actualFlow
end
-- \brief Transfers power from source node to it's network, if sides is set then power will be only transfered to network connected to that sides
-- \param pos Vector with position of source node
-- \param (optional) sides table with Vectors
-- \param (optional) flowOverride number
-- \returns two values: true if any neighbouring node has room for more power, false otherwise
-- true if any power was transferred, false otherwise
industrialtest.api.powerFlow=function(pos,sides,flowOverride)
local meta=minetest.get_meta(pos)
-- if machine doesn't have network map then it's not capable of transferring power
local network=industrialtest.api.getNetwork(meta)
if not network or #network==0 then
return false,false
end
local endpointCount=0
for _,endpoint in ipairs(network) do
local endpointMeta=minetest.get_meta(endpoint.position)
if not industrialtest.api.isFullyCharged(endpointMeta) and (not sides or sides[endpoint.sourceSide]) then
endpointCount=endpointCount+1
end
end
if endpointCount==0 then
return false,false
end
local powerDistribution=math.floor((flowOverride and flowOverride or meta:get_int("industrialtest.powerFlow"))/endpointCount)
local transferred=false
local roomAvailable=false
for _,endpoint in ipairs(network) do
if not sides or sides[endpoint.sourceSide] then
local endpointMeta=minetest.get_meta(endpoint.position)
if powerDistribution<=endpoint.flow then
local transferredPower=industrialtest.api.transferPower(meta,endpointMeta,powerDistribution)
if transferredPower>0 then
transferred=true
end
local def=minetest.registered_nodes[minetest.get_node(endpoint.position).name]
if def then
local updateFormspec=def._industrialtest_updateFormspec
if updateFormspec then
updateFormspec(endpoint.position)
end
local onPowerFlow=def._industrialtest_onPowerFlow
if onPowerFlow and transferredPower>0 then
onPowerFlow(endpoint.position,industrialtest.api.getOppositeSide(endpoint.side),transferredPower)
end
end
minetest.get_node_timer(endpoint.position):start(industrialtest.updateDelay)
if not industrialtest.api.isFullyCharged(endpointMeta) then
roomAvailable=true
end
else
minetest.remove_node(endpoint.position)
industrialtest.internal.explode(endpoint.position,2)
end
end
end
return roomAvailable,transferred
end
local function addNodeToNetwork(pos,networkMasterPos)
local meta=minetest.get_meta(pos)
local networks={}
if meta:contains("industrialtest.networks") then
networks=minetest.deserialize(meta:get_string("industrialtest.networks"))
end
for _,network in ipairs(networks) do
if network.x==networkMasterPos.x and network.y==networkMasterPos.y and network.z==networkMasterPos.z then
return
end
end
table.insert(networks,networkMasterPos)
meta:set_string("industrialtest.networks",minetest.serialize(networks))
end
local function clampFlow(pos,flow)
local def=minetest.registered_nodes[minetest.get_node(pos).name]
local newFlow
if def.groups and def.groups._industrialtest_cable then
newFlow=def._industrialtest_cableFlow
else
local meta=minetest.get_meta(pos)
newFlow=meta:get_int("industrialtest.powerFlow")
end
return math.min(flow,newFlow)
end
-- \brief Creates network map starting from node at pos, optionally omitting node at omit
-- \param pos vector
-- \param (optional) addCables bool
-- \param (optional) omit Vector
-- \returns table with network map
industrialtest.api.createNetworkMap=function(pos,addCables,omit)
local workers={}
local map={}
local connections=industrialtest.api.getConnections(pos,"i")
if #connections==0 then
return map
end
local sides={
["-1,0,0"]=1,
["1,0,0"]=2,
["0,-1,0"]=3,
["0,1,0"]=4,
["0,0,-1"]=5,
["0,0,1"]=6
}
local serializedSourcePos=pos.x..","..pos.y..","..pos.z
local visitedNodes={[serializedSourcePos]=true}
for _,conn in ipairs(connections) do
if not omit or conn.x~=omit.x or conn.y~=omit.y or conn.z~=omit.z then
visitedNodes[conn.x..","..conn.y..","..conn.z]=true
addNodeToNetwork(conn,pos)
local sideVector=vector.subtract(conn,pos)
local serializedSideVector=sideVector.x..","..sideVector.y..","..sideVector.z
local def=minetest.registered_nodes[minetest.get_node(conn).name]
if def.groups._industrialtest_cable then
table.insert(workers,{
position=conn,
targetPosition=conn,
distance=1,
flow=def._industrialtest_cableFlow,
targetFlow=0,
sourceSide=industrialtest.api.normalizeSide(pos,sides[serializedSideVector])
})
if addCables then
table.insert(map,{
position=conn,
distance=0
})
end
else
local meta=minetest.get_meta(conn)
table.insert(map,{
position=conn,
distance=0,
flow=meta:get_int("industrialtest.powerFlow"),
side=sides[serializedSideVector],
sourceSide=industrialtest.api.normalizeSide(pos,sides[serializedSideVector])
})
end
end
end
while #workers>0 do
for i=1,#workers do
local worker=workers[i]
connections=industrialtest.api.getConnections(worker.position,"i")
if #connections==0 then
table.remove(workers,i)
break
else
local directionAssigned=false
local foundNewNode=false
for _,conn in ipairs(connections) do
if not omit or conn.x~=omit.x or conn.y~=omit.y or conn.z~=omit.z then
local serializedPos=conn.x..","..conn.y..","..conn.z
if not visitedNodes[serializedPos] then
local def=minetest.registered_nodes[minetest.get_node(conn).name]
visitedNodes[serializedPos]=true
foundNewNode=true
addNodeToNetwork(conn,pos)
if def.groups._industrialtest_cable then
if directionAssigned then
table.insert(workers,{
position=conn,
targetPosition=conn,
distance=worker.distance+1,
flow=clampFlow(conn,worker.flow),
targetFlow=0,
sourceSide=worker.sourceSide
})
else
worker.targetPosition=conn
worker.distance=worker.distance+1
worker.targetFlow=clampFlow(conn,worker.flow)
directionAssigned=true
end
if addCables then
table.insert(map,{
position=conn,
distance=worker.distance+1,
})
end
else
local sideVector=vector.subtract(conn,worker.position)
table.insert(map,{
position=conn,
distance=worker.distance,
flow=clampFlow(conn,worker.flow),
side=sides[sideVector.x..","..sideVector.y..","..sideVector.z],
sourceSide=worker.sourceSide
})
if #connections==1 then
foundNewNode=false
break
end
end
end
end
end
if not foundNewNode then
table.remove(workers,i)
break
end
worker.position=worker.targetPosition
worker.flow=worker.targetFlow
end
end
end
return map
end
industrialtest.api.removeNodeFromNetwork=function(pos,nodePos)
local meta=minetest.get_meta(pos)
local network=minetest.deserialize(meta:get_string("industrialtest.network"))
local removed=false
for key,node in ipairs(network) do
if node.position.x==nodePos.x and node.position.y==nodePos.y and node.position.z==nodePos.z then
table.remove(network,key)
removed=true
break
end
end
if removed then
meta:set_string("industrialtest.network",minetest.serialize(network))
end
end
-- \brief Creates network map and writes it to node metadata at pos, optionally omitting node at omit
-- \param pos Vector
-- \param (optional) omit Vector
-- \returns nil
industrialtest.api.createNetworkMapForNode=function(pos,omit)
local meta=minetest.get_meta(pos)
local network=industrialtest.api.createNetworkMap(pos,false,omit)
meta:set_string("industrialtest.network",minetest.serialize(network))
end
-- \brief Returns true if meta contains network map, false otherwise
-- \param meta MetaDataRef
-- \returns bool
industrialtest.api.isNetworkMaster=function(meta)
return meta:contains("industrialtest.network")
end
-- \brief Returns network table if node containing meta belongs to any networks, false otherwise
-- \param meta MetaDataRef
-- \returns bool or table
industrialtest.api.isAttachedToNetwork=function(meta)
if not meta:contains("industrialtest.networks") then
return false
end
local networks=minetest.deserialize(meta:get_string("industrialtest.networks"))
if #networks==0 then
return false
end
return networks
end
-- \brief Returns network master network from it's meta, if meta doesn't contain network map then function returns false
-- \param meta MetaDataRef
-- \returns table or bool
industrialtest.api.getNetwork=function(meta)
if not meta:contains("industrialtest.network") then
return false
end
return minetest.deserialize(meta:get_string("industrialtest.network"))
end
-- \brief Returns opposite side of provided one
-- \param side Side number. See industrialtest.api.addPowerStorage for order
-- \returns Opposite side
industrialtest.api.getOppositeSide=function(side)
return (side%2==0 and side-1 or side+1)
end
-- \brief Returns connections of node with power storage. If direction is "i" only input connections will be returned, if direction is "o" only output connections
-- will be returned, if it's not provided all connections will be returned.
-- \param pos Vector
-- \param (optional) direction string
-- \returns table
industrialtest.api.getConnections=function(pos,direction)
local result={}
local neighbourPositions={
vector.offset(pos,-1,0,0),
vector.offset(pos,1,0,0),
vector.offset(pos,0,-1,0),
vector.offset(pos,0,1,0),
vector.offset(pos,0,0,-1),
vector.offset(pos,0,0,1)
}
local sourceMeta=minetest.get_meta(pos)
local sourceDef=minetest.registered_nodes[minetest.get_node(pos).name]
local directionOutput=(not direction or direction=="o")
local directionInput=(not direction or direction=="i")
for key,conn in ipairs(neighbourPositions) do
local meta=minetest.get_meta(conn)
local def=minetest.registered_nodes[minetest.get_node(conn).name]
local normalizedKey=industrialtest.api.normalizeSide(pos,key)
local powerOutput=(sourceDef.groups._industrialtest_cable or industrialtest.api.isPowerOutput(sourceMeta,normalizedKey))
local powerInput=(sourceDef.groups._industrialtest_cable or industrialtest.api.isPowerInput(sourceMeta,normalizedKey))
if def.groups._industrialtest_cable or industrialtest.api.hasPowerStorage(meta) then
local side=industrialtest.api.normalizeSide(conn,industrialtest.api.getOppositeSide(normalizedKey))
if (powerOutput and directionInput and (def.groups._industrialtest_cable or industrialtest.api.isPowerInput(meta,side))) or ((def.groups._industrialtest_cable or industrialtest.api.isPowerOutput(meta,side)) and powerInput and directionOutput) then
table.insert(result,conn)
end
end
end
return result
end
-- \brief Changes node's power IO config. Function doesn't check if meta actually contains power storage.
-- \param meta MetaDataRef of node which power IO config should be changed
-- \param side Side number. See industrialtest.api.addPowerStorage to check order.
-- \param mode Side mode. See industrialtest.api.addPowerStorage for possible values.
-- \returns nil
industrialtest.api.changeIoConfig=function(meta,side,mode)
local ioConfig=meta:get_string("industrialtest.ioConfig")
ioConfig=string.sub(ioConfig,1,side-1)..mode..string.sub(ioConfig,side+1)
meta:set_string("industrialtest.ioConfig",ioConfig)
end
-- \brief Checks if provided side is power input
-- \param meta MetaDataRef of node
-- \param side Side number. See industrialtest.api.addPowerStorage to check order.
-- \returns true if provided side is power input, false otherwise
industrialtest.api.isPowerInput=function(meta,side)
local ioConfig=meta:get_string("industrialtest.ioConfig")
local mode=string.sub(ioConfig,side,side)
return (mode=="i" or mode=="a")
end
-- \brief Checks if provided side is power output
-- \param meta MetaDataRef of node
-- \param side Side number. See industrialtest.api.addPowerStorage to check order.
-- \returns true if provided side is power output, false otherwise
industrialtest.api.isPowerOutput=function(meta,side)
local ioConfig=meta:get_string("industrialtest.ioConfig")
local mode=string.sub(ioConfig,side,side)
return (mode=="o" or mode=="a")
end
-- \brief Registers dust of certain resource
-- \param name Technical name of resource
-- \param displayName Display name of resource
-- \param resources List of tables with following keys: <output>, <recipe>, [count(1)]
-- <> - required, [] - optional, () - default value
-- \param color HTML color of dust
-- \param registerMaceratorRecipe If true macerator recipe for dust will be registered
-- \returns nil
industrialtest.api.registerResourceDust=function(name,displayName,resources,color,registerMaceratorRecipe)
minetest.register_craftitem("industrialtest:"..name.."_dust",{
description=S(displayName.." Dust"),
inventory_image="industrialtest_dust.png",
color=color
})
if registerMaceratorRecipe then
for _,value in ipairs(resources) do
industrialtest.api.registerMaceratorRecipe({
output="industrialtest:"..name.."_dust "..(value.count or 1),
recipe=value.resource
})
end
end
end
-- \brief Registers plate of certain resource
-- \param name Technical name of resource
-- \param displayName Display name of resource
-- \param resources List of tables with following keys: <output>, <recipe>, [count(1)]
-- <> - required, [] - optional, () - default value
-- \param color HTML color of plate
-- \param registerCompressorRecipe If true compressor recipe for plate will be registered
-- \returns nil
industrialtest.api.registerPlate=function(name,displayName,resources,color,registerCompressorRecipe)
minetest.register_craftitem("industrialtest:"..name,{
description=displayName,
inventory_image="industrialtest_plate.png",
inventory_overlay="industrialtest_plate_overlay.png",
color=color
})
if registerCompressorRecipe then
for _,value in ipairs(resources) do
industrialtest.api.registerCompressorRecipe({
output="industrialtest:"..name.." "..(value.count or 1),
recipe=value.resource
})
end
end
end
-- \brief Registers cell with certain fluid
-- \param name Technical name of cell
-- \param displayName Display name of cell
-- \param node Node which can be picked up with this cell
-- \returns nil
industrialtest.api.registerStorageCell=function(name,displayName,node,modname,color)
color = color or "#ffffffff"
if not modname then
modname="industrialtest"
end
minetest.register_craftitem("industrialtest:"..name.."_cell",{
description=S(displayName.." Cell"),
inventory_image="industrialtest_cell_fluid.png",
inventory_overlay="industrialtest_cell_casing.png",
color=color,
on_place=function(itemstack,user,pointed)
if pointed.type~="node" or not user or not user:is_player() then
return nil
end
local node=minetest.get_node_or_nil(pointed.above)
local storage=industrialtest.api.getStorageCell("industrialtest:"..name.."_cell")
if storage.node then
if node.name~="air" and node.name~=storage.node then
return nil
end
minetest.set_node(pointed.above,{name=storage.node})
if itemstack:get_count()==1 then
itemstack:set_name("industrialtest:empty_cell")
else
local inv=user:get_inventory()
inv:add_item("main",ItemStack("industrialtest:empty_cell"))
itemstack:take_item()
end
return itemstack
end
return nil
end
})
industrialtest.api.storageCells["industrialtest:"..name.."_cell"]={
name="industrialtest:"..name.."_cell",
node=node
}
end
-- \brief Returns registred storage cell by name
-- \param name Storage cell name
-- \returns Table with following keys: name, node or nil in case of failure
industrialtest.api.getStorageCell=function(name)
return industrialtest.api.storageCells[name]
end
-- \brief Returns registered storage cells by node
-- \param node Node ID
-- \returns Table with following keys: name, node or nil in case of failure
industrialtest.api.getStorageCellByNode=function(node)
for _,value in pairs(industrialtest.api.storageCells) do
if value.node==node then
return value
end
end
return nil
end
-- \brief Registers macerator recipe
-- \param config Table with keys: <output>, <recipe>, [time(2)]
-- \returns nil
industrialtest.api.registerMaceratorRecipe=function(config)
local definition={
output=config.output or "",
recipe=config.recipe or "",
time=config.time or 2
}
industrialtest.api.maceratorRecipes[definition.recipe]=definition
end
-- \brief Returns macerator recipe result
-- \param recipe String ID of resulting conten
-- \returns Table with following keys: output, recipe, time
industrialtest.api.getMaceratorRecipeResult=function(recipe)
return industrialtest.api.maceratorRecipes[recipe]
end
-- \brief Registers compressor recipe
-- \param config Table with following keys: <output>, <recipe>, [time(2)], [count(1)]
-- \returns nil
industrialtest.api.registerCompressorRecipe=function(config)
local definition={
output=config.output or "",
recipe=config.recipe or "",
time=config.time or 2,
count=config.count or 1
}
industrialtest.api.compressorRecipes[definition.recipe]=definition
end
-- \brief Returns macerator recipe result
-- \param recipe String ID of resulting conten
-- \returns Table with following keys: output, recipe, time
industrialtest.api.getCompressorRecipeResult=function(recipe)
return industrialtest.api.compressorRecipes[recipe]
end
industrialtest.api.registerExtractorRecipe=function(config)
local definition={
output=config.output or "",
recipe=config.recipe or "",
time=config.time or 2
}
industrialtest.api.extractorRecipes[definition.recipe]=definition
end
industrialtest.api.getExtractorRecipeResult=function(recipe)
return industrialtest.api.extractorRecipes[recipe]
end
industrialtest.api.registerCableFormerRecipe=function(config)
local definition={
output=config.output or "",
recipe=config.recipe or "",
time=config.time or 2
}
industrialtest.api.cableFormerRecipes[definition.recipe]=definition
end
industrialtest.api.getCableFormerRecipeResult=function(recipe)
return industrialtest.api.cableFormerRecipes[recipe]
end
-- \brief Registers fuel that can be used in geothermal generator
-- \param fuel Table with following keys: <name>, <calorificValue>, <storageItems>
-- which is a table containing items which are tables with following keys: <name>, <leftover>
-- \returns nil
industrialtest.api.registerGeothermalGeneratorFuel=function(config)
local definition={
name=config.name or "",
calorificValue=config.calorificValue or 0,
texture=config.texture or "industrialtest_gui_fluid_bg.png",
storageItems=config.storageItems or {}
}
industrialtest.api.geothermalGeneratorFuels[definition.name]=definition
end
-- \brief Returns generator fuel information
-- \param name Name of fuel
-- \returns Table with following keys: name, calorificValue, storageItems
industrialtest.api.getGeothermalGeneratorFuel=function(name)
return industrialtest.api.geothermalGeneratorFuels[name]
end
-- \brief Returns generator fuel information by item name
-- \param name ID of item
-- \returns Table with following keys: name, calorificValue, storageItems or nil in case of failure
industrialtest.api.getGeothermalGeneratorFuelByItem=function(name)
for _,value in pairs(industrialtest.api.geothermalGeneratorFuels) do
for _,item in ipairs(value.storageItems) do
if item.name==name then
return value
end
end
end
return nil
end
-- \brief Registers fuel that can be used in water mill
-- \param fuel Table with following keys: <name>, <calorificValue>, <storageItems>
-- which is a table containing items which are tables with following keys: <name>, <leftover>
-- \returns nil
industrialtest.api.registerWaterMillFuel=function(config)
local definition={
name=config.name or "",
calorificValue=config.calorificValue or 0,
texture=config.texture or "industrialtest_gui_fluid_bg.png",
storageItems=config.storageItems or {}
}
industrialtest.api.waterMillFuels[definition.name]=definition
end
-- \brief Returns water mill fuel information
-- \param name Name of fuel
-- \returns Table with following keys: name, calorificValue, storageItems
industrialtest.api.getWaterMillFuel=function(name)
return industrialtest.api.waterMillFuels[name]
end
-- \brief Returns water mill fuel information by item name
-- \param name ID of item
-- \returns Table with following keys: name, calorificValue, storageItems or nil in case of failure
industrialtest.api.getWaterMillFuelByItem=function(name)
for _,value in pairs(industrialtest.api.waterMillFuels) do
for _,item in ipairs(value.storageItems) do
if item.name==name then
return value
end
end
end
return nil
end
-- \brief Registers Rotary Macerator recipe modifier
-- \param config table
-- \returns nil
industrialtest.api.registerRotaryMaceratorModifier=function(config)
local definition={
name=config.name or "",
modifier=config.modifier or "",
output=config.output or "",
time=config.time or 2,
uses=config.uses or 1,
modifierLeftover=config.modifierLeftover
}
industrialtest.api.rotaryMaceratorModifiers[definition.name.." "..config.modifier]=definition
end
-- \brief Returns modified Rotary Macerator recipe by item and modifier
-- \param name string
-- \param modifier string
-- \returns table
industrialtest.api.getRotaryMaceratorModifier=function(name,modifier)
return industrialtest.api.rotaryMaceratorModifiers[name.." "..modifier]
end
-- \brief Returns machine speed in items per operation
-- \param meta MetaDataRef
-- \returns number
industrialtest.api.getMachineSpeed=function(meta)
return meta:contains("industrialtest.speed") and meta:get_int("industrialtest.speed") or 1
end

50
api/common.lua Normal file
View File

@ -0,0 +1,50 @@
-- IndustrialTest
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
industrialtest.api={
maceratorRecipes={},
compressorRecipes={},
extractorRecipes={},
cableFormerRecipes={},
geothermalGeneratorFuels={},
waterMillFuels={},
rotaryMaceratorModifiers={},
storageCells={},
tags={}
}
industrialtest.api.lvPowerFlow=600
industrialtest.api.mvPowerFlow=2400
industrialtest.api.hvPowerFlow=10200
industrialtest.api.evPowerFlow=40800
industrialtest.api.ivPowerFlow=163800
function industrialtest.internal.clamp(num,min,max)
return math.max(math.min(num,max),min)
end
function industrialtest.internal.unpackTableInto(first,second)
for k,v in pairs(second) do
first[k]=v
end
end
-- \brief Returns machine speed in items per operation
-- \param meta MetaDataRef
-- \returns number
function industrialtest.api.getMachineSpeed(meta)
return meta:contains("industrialtest.speed") and meta:get_int("industrialtest.speed") or 1
end

132
api/fluid.lua Normal file
View File

@ -0,0 +1,132 @@
-- IndustrialTest
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local function createItemFluidStorageText(itemstack)
local meta=itemstack:get_meta()
local fluidCapacity=meta:get_int("industrialtest.fluidCapacity")
local fluidAmount=meta:get_int("industrialtest.fluidAmount")
local lowerLimit=math.floor(fluidCapacity*0.25)
local color=(fluidAmount>lowerLimit and "#0000FF" or "#FF0000")
return minetest.colorize(color,S("@1 / @2 mB",fluidAmount,fluidCapacity))
end
-- \brief Check if itemstack contains fluid storage
-- \param itemstack ItemStack
-- \returns bool
function industrialtest.api.itemHasFluidStorage(itemstack)
local values={"industrialtest.fluidAmount","industrialtest.fluidCapacity"}
local meta=itemstack:get_meta()
for _,value in ipairs(values) do
if not meta:contains(value) then
return false
end
end
return true
end
-- \brief Check if fluid storage in meta is full
-- \param meta MetaDataRef
-- \returns bool
function industrialtest.api.isFluidStorageFull(meta)
return meta:get_int("industrialtest.fluidAmount")>=meta:get_int("industrialtest.fluidCapacity")
end
-- \brief Check if item fluid storage is full
-- \param itemstack ItemStack
-- \returns bool
function industrialtest.api.isItemFluidStorageFull(itemstack)
local meta=itemstack:get_meta()
return industrialtest.api.isFluidStorageFull(meta)
end
-- \brief Check if fluid storage in meta is empty
-- \param meta MetaDataRef
-- \returns bool
function industrialtest.api.isFluidStorageEmpty(meta)
return meta:get_int("industrialtest.fluidAmount")==0
end
-- \brief Check if item fluid storage is empty
-- \param itemstack ItemStack
-- \returns bool
function industrialtest.api.isItemFluidStorageEmpty(itemstack)
local meta=itemstack:get_meta()
return industrialtest.api.isFluidStorageEmpty(meta)
end
-- \brief Updates itemstack description and wear depending on contained fluid
-- \param itemstack ItemStack
-- \returns nil
function industrialtest.api.updateItemFluidText(itemstack)
local meta=itemstack:get_meta()
if industrialtest.mtgAvailable then
local def=itemstack:get_definition()
local fluidStorageText=createItemFluidStorageText(itemstack)
meta:set_string("description",string.format("%s\n%s",def.description,fluidStorageText))
elseif industrialtest.mclAvailable then
tt.reload_itemstack_description(itemstack)
end
itemstack:set_wear(65535-meta:get_int("industrialtest.fluidAmount")/meta:get_int("industrialtest.fluidCapacity")*65534)
end
-- \brief Adds fluid amount to item fluid storage
-- \param itemstack ItemStack
-- \param amount number
-- \returns number
function industrialtest.api.addFluidToItem(itemstack,amount)
local meta=itemstack:get_meta()
if not industrialtest.api.itemHasFluidStorage(itemstack) then
return 0
end
local fluidAmount=meta:get_int("industrialtest.fluidAmount")
local fluidCapacity=meta:get_int("industrialtest.fluidCapacity")
local prevFluidAmount=fluidAmount
fluidAmount=industrialtest.internal.clamp(fluidAmount+amount,0,fluidCapacity)
meta:set_int("industrialtest.fluidAmount",fluidAmount)
industrialtest.api.updateItemFluidText(itemstack)
return fluidAmount-prevFluidAmount
end
-- \brief Adds fluid to destination itemstack while subtracting it from source itemstack's metadata
-- \param srcItemstack ItemStack
-- \param itemstack ItemStack
-- \param amount number
-- \returns number
function industrialtest.api.transferFluidToItem(srcItemstack,itemstack,amount)
local meta=srcItemstack:get_meta()
local flow=math.min(meta:get_int("industrialtest.fluidAmount"),amount)
if flow==0 then
return 0
end
local actualFlow=industrialtest.api.addFluidToItem(itemstack,flow)
meta:set_int("industrialtest.fluidAmount",meta:get_int("industrialtest.fluidAmount")-actualFlow)
industrialtest.api.updateItemFluidText(srcItemstack)
return actualFlow
end
if industrialtest.mclAvailable then
tt.register_snippet(function(itemstring,toolCapabilities,itemstack)
if not itemstack then
return nil
end
if not industrialtest.api.itemHasFluidStorage(itemstack) then
return nil
end
return createItemFluidStorageText(itemstack),false
end)
end

460
api/network.lua Normal file
View File

@ -0,0 +1,460 @@
-- IndustrialTest
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
local function addNodeToNetwork(pos,networkMasterPos)
local meta=minetest.get_meta(pos)
local networks={}
if meta:contains("industrialtest.networks") then
networks=minetest.deserialize(meta:get_string("industrialtest.networks"))
end
for _,network in ipairs(networks) do
if network.x==networkMasterPos.x and network.y==networkMasterPos.y and network.z==networkMasterPos.z then
return
end
end
table.insert(networks,networkMasterPos)
meta:set_string("industrialtest.networks",minetest.serialize(networks))
end
local function clampFlow(pos,flow)
local def=minetest.registered_nodes[minetest.get_node(pos).name]
local newFlow
if def.groups and def.groups._industrialtest_cable then
newFlow=def._industrialtest_cableFlow
else
local meta=minetest.get_meta(pos)
newFlow=meta:get_int("industrialtest.powerFlow")
end
return math.min(flow,newFlow)
end
-- \brief Finds path from pos to dest in network. Function finished if either dest is found or every node was visited
-- \param pos Vector
-- \param dest Vector
-- \returns table or nil
function industrialtest.api.findPathInNetwork(pos,dest)
local connections=industrialtest.api.getConnections(pos,"i")
if #connections==0 then
return nil
end
local workers={}
local serializedSourcePos=pos.x..","..pos.y..","..pos.z
local visitedNodes={[serializedSourcePos]=true}
for _,conn in ipairs(connections) do
local sideVector=vector.subtract(conn,pos)
table.insert(workers,{
position=conn,
direction=sideVector,
path={[1]=conn}
})
end
while #workers>0 do
for i=1,#workers do
local worker=workers[i]
local serializedPos=worker.position.x..","..worker.position.y..","..worker.position.z
if visitedNodes[serializedPos] then
table.remove(workers,i)
break
end
visitedNodes[serializedPos]=true
if worker.position.x==dest.x and worker.position.y==dest.y and worker.position.z==dest.z then
return worker.path
end
local def=minetest.registered_nodes[minetest.get_node(worker.position).name]
if def and def.groups and def.groups._industrialtest_cable then
connections=industrialtest.api.getConnections(worker.position,"i")
for j=1,#connections do
local direction=vector.subtract(connections[j],worker.position)
local oppositeDirection=vector.multiply(worker.direction,vector.new(-1,-1,-1))
if direction.x~=oppositeDirection.x or direction.y~=oppositeDirection.y or direction.z~=oppositeDirection.z then
if worker.direction.x~=direction.x or worker.direction.y~=direction.y or worker.direction.z~=direction.z then
table.insert(worker.path,worker.position)
end
for c=1,#connections do
local nextDirection=vector.subtract(connections[c],worker.position)
if c~=j and (nextDirection.x~=oppositeDirection.x or nextDirection.y~=oppositeDirection.y or nextDirection.z~=oppositeDirection.z) then
local newWorker={
position=connections[c],
direction=nextDirection,
path=table.copy(worker.path)
}
table.insert(newWorker.path,worker.position)
table.insert(workers,newWorker)
end
end
worker.direction=direction
worker.position=connections[j]
break
end
end
if #connections>2 then
break
end
else
table.remove(workers,i)
break
end
end
end
return nil
end
-- \brief Goes through path vertices specified by path running callback on each node.
-- Function finishes if either callback returns false or entire path is went over.
-- \param path table
-- \param callback function
-- \returns nil
function industrialtest.api.walkPath(path,callback)
local pos=path[1]
for i=2,#path do
local pathNode=path[i]
local direction=vector.normalize(vector.subtract(pathNode,pos))
while pos.x~=pathNode.x or pos.y~=pathNode.y or pos.z~=pathNode.z do
if not callback(pos) then
return
end
pos=vector.add(pos,direction)
end
end
end
-- \brief Transfers power from source node to it's network, if sides is set then power will be only transfered to network connected to that sides
-- \param pos Vector with position of source node
-- \param (optional) sides table with Vectors
-- \param (optional) flowOverride number
-- \returns two values: true if any neighbouring node has room for more power, false otherwise
-- true if any power was transferred, false otherwise
function industrialtest.api.powerFlow(pos,sides,flowOverride)
local meta=minetest.get_meta(pos)
-- if machine doesn't have network map then it's not capable of transferring power
local network=industrialtest.api.getNetwork(meta)
if not network or #network==0 then
return false,false
end
local endpointCount=0
for _,endpoint in ipairs(network) do
local endpointMeta=minetest.get_meta(endpoint.position)
if not industrialtest.api.isFullyCharged(endpointMeta) and (not sides or sides[endpoint.sourceSide]) then
endpointCount=endpointCount+1
end
end
if endpointCount==0 then
return false,false
end
local ioConfig=industrialtest.api.getIoConfig(meta)
local transferred=false
local roomAvailable=false
for _,endpoint in ipairs(network) do
if not sides or sides[endpoint.sourceSide] then
local flow
if flowOverride then
flow=flowOverride
elseif type(ioConfig)=="string" then
flow=math.min(meta:get_int("industrialtest.powerAmount"),meta:get_int("industrialtest.powerFlow"))
else
flow=math.min(meta:get_int("industrialtest.powerAmount"),ioConfig[endpoint.sourceSide].flow)
end
local powerDistribution=math.floor(flow/endpointCount)
local endpointMeta=minetest.get_meta(endpoint.position)
if powerDistribution<=endpoint.flow then
local transferredPower=industrialtest.api.transferPower(meta,endpointMeta,powerDistribution)
if transferredPower>0 then
transferred=true
end
local def=minetest.registered_nodes[minetest.get_node(endpoint.position).name]
if def and def._industrialtest_self then
def._industrialtest_self:updateFormspec(endpoint.position)
if def._industrialtest_self.onPowerFlow and transferredPower>0 then
def._industrialtest_self:onPowerFlow(endpoint.position,industrialtest.api.getOppositeSide(endpoint.side),transferredPower)
end
def._industrialtest_self:triggerIfNeeded(endpoint.position)
else
-- Support for bare definitions that don't use industrialtest pseudo-OOP
minetest.get_node_timer(endpoint.position):start(industrialtest.config.updateDelay)
end
if not industrialtest.api.isFullyCharged(endpointMeta) then
roomAvailable=true
end
else
local path=industrialtest.api.findPathInNetwork(pos,endpoint.position)
if path and #path>0 then
table.insert(path,endpoint.position)
local removed=false
industrialtest.api.walkPath(path,function(pathPos)
local def=minetest.registered_nodes[minetest.get_node(pathPos).name]
if not def or not def.groups or not def.groups._industrialtest_cable then
return false
end
if powerDistribution>def._industrialtest_cableFlow then
removed=true
minetest.swap_node(pathPos,{
name="air"
})
minetest.remove_node(pathPos)
minetest.check_for_falling(pathPos)
minetest.sound_play("default_cool_lava",{
pos=pathPos,
max_hear_distance=5,
gain=0.7
})
end
return true
end)
if not removed and powerDistribution>endpoint.originalFlow then
minetest.remove_node(endpoint.position)
industrialtest.internal.explode(endpoint.position,2)
end
industrialtest.api.createNetworkMapForNode(pos)
end
end
end
end
return roomAvailable,transferred
end
-- \brief Creates network map starting from node at pos, optionally omitting node at omit
-- \param pos vector
-- \param (optional) addCables bool
-- \param (optional) omit Vector
-- \returns table with network map
function industrialtest.api.createNetworkMap(pos,addCables,omit)
local map={}
local connections=industrialtest.api.getConnections(pos,"i")
if #connections==0 then
return map
end
local sourceMeta=minetest.get_meta(pos)
local workers={}
local sides={
["-1,0,0"]=1,
["1,0,0"]=2,
["0,-1,0"]=3,
["0,1,0"]=4,
["0,0,-1"]=5,
["0,0,1"]=6
}
local serializedSourcePos=pos.x..","..pos.y..","..pos.z
local visitedNodes={[serializedSourcePos]=true}
for _,conn in ipairs(connections) do
if not omit or conn.x~=omit.x or conn.y~=omit.y or conn.z~=omit.z then
local sideVector=vector.subtract(conn,pos)
local serializedSideVector=sideVector.x..","..sideVector.y..","..sideVector.z
local sourceSide=industrialtest.api.normalizeSide(pos,sides[serializedSideVector])
table.insert(workers,{
position=conn,
direction=sideVector,
distance=1,
flow=industrialtest.api.getPowerFlowForSide(sourceMeta,sourceSide),
sourceSide=sourceSide
})
end
end
while #workers>0 do
for i=1,#workers do
local worker=workers[i]
local serializedPos=worker.position.x..","..worker.position.y..","..worker.position.z
if visitedNodes[serializedPos] or (omit and omit==worker.position) then
table.remove(workers,i)
break
end
visitedNodes[serializedPos]=true
addNodeToNetwork(worker.position,pos)
local def=minetest.registered_nodes[minetest.get_node(worker.position).name]
if def and def.groups and def.groups._industrialtest_cable then
if addCables then
table.insert(map,{
position=worker.position,
distance=worker.distance,
flow=clampFlow(worker.position,worker.flow),
side=0,
sourceSide=worker.sourceSide
})
end
connections=industrialtest.api.getConnections(worker.position,"i")
if #connections==0 then
table.remove(workers,i)
break
end
worker.flow=clampFlow(worker.position,worker.flow)
worker.distance=worker.distance+1
for i=2,#connections do
table.insert(workers,{
position=connections[i],
direction=vector.subtract(connections[i],worker.position),
distance=worker.distance,
flow=worker.flow,
sourceSide=worker.sourceSide
})
end
worker.direction=vector.subtract(connections[1],worker.position)
worker.position=connections[1]
if #connections>=2 then
break
end
else
local meta=minetest.get_meta(worker.position)
local incomingSide=industrialtest.api.normalizeSide(worker.position,sides[worker.direction.x..","..worker.direction.y..","..worker.direction.z])
local connectionSide=industrialtest.api.getOppositeSide(incomingSide)
local flow=industrialtest.api.getPowerFlowForSide(meta,connectionSide)
table.insert(map,{
position=worker.position,
distance=worker.distance,
flow=math.min(worker.flow,flow),
originalFlow=flow,
side=connectionSide,
sourceSide=worker.sourceSide
})
table.remove(workers,i)
break
end
end
end
return map
end
function industrialtest.api.removeNodeFromNetwork(pos,nodePos)
local meta=minetest.get_meta(pos)
if not meta:contains("industrialtest.network") then
return
end
local network=minetest.deserialize(meta:get_string("industrialtest.network"))
local removed=false
for key,node in ipairs(network) do
if node.position.x==nodePos.x and node.position.y==nodePos.y and node.position.z==nodePos.z then
table.remove(network,key)
removed=true
break
end
end
if removed then
meta:set_string("industrialtest.network",minetest.serialize(network))
end
end
-- \brief Creates network map and writes it to node metadata at pos, optionally omitting node at omit
-- \param pos Vector
-- \param (optional) omit Vector
-- \returns nil
function industrialtest.api.createNetworkMapForNode(pos,omit)
local meta=minetest.get_meta(pos)
local network=industrialtest.api.createNetworkMap(pos,false,omit)
meta:set_string("industrialtest.network",minetest.serialize(network))
end
-- \brief Returns true if meta contains network map, false otherwise
-- \param meta MetaDataRef
-- \returns bool
function industrialtest.api.isNetworkMaster(meta)
return meta:contains("industrialtest.network")
end
-- \brief Returns network table if node containing meta belongs to any networks, false otherwise
-- \param meta MetaDataRef
-- \returns bool or table
function industrialtest.api.isAttachedToNetwork(meta)
if not meta:contains("industrialtest.networks") then
return false
end
local networks=minetest.deserialize(meta:get_string("industrialtest.networks"))
if #networks==0 then
return false
end
return networks
end
-- \brief Returns network master network from it's meta, if meta doesn't contain network map then function returns false
-- \param meta MetaDataRef
-- \returns table or bool
function industrialtest.api.getNetwork(meta)
if not meta:contains("industrialtest.network") then
return false
end
return minetest.deserialize(meta:get_string("industrialtest.network"))
end
-- \brief Returns amount of power that will flow from specified network master
-- \param pos Vector
-- \returns number
function industrialtest.api.getFlowingCurrent(pos)
local meta=minetest.get_meta(pos)
if not industrialtest.api.hasPowerStorage(meta) or meta:get_int("industrialtest.powerAmount")==0 then
return 0
end
local network=industrialtest.api.getNetwork(meta)
if not network then
return 0
end
local amount=meta:get_int("industrialtest.powerAmount")
if amount==0 then
return 0
end
local demand=0
for _,endpoint in ipairs(network) do
local endpointMeta=minetest.get_meta(endpoint.position)
if industrialtest.api.hasPowerStorage(endpointMeta) then
demand=demand+math.min(endpointMeta:get_int("industrialtest.powerCapacity")-endpointMeta:get_int("industrialtest.powerAmount"),endpoint.flow)
end
end
return math.min(amount,demand)
end
-- \brief Returns connections of node with power storage. If direction is "i" only input connections will be returned, if direction is "o" only output connections
-- will be returned, if it's not provided all connections will be returned.
-- \param pos Vector
-- \param (optional) direction string
-- \returns table
function industrialtest.api.getConnections(pos,direction)
local result={}
local neighbourPositions={
vector.offset(pos,-1,0,0),
vector.offset(pos,1,0,0),
vector.offset(pos,0,-1,0),
vector.offset(pos,0,1,0),
vector.offset(pos,0,0,-1),
vector.offset(pos,0,0,1)
}
local sourceMeta=minetest.get_meta(pos)
local sourceDef=minetest.registered_nodes[minetest.get_node(pos).name]
local directionOutput=(not direction or direction=="o")
local directionInput=(not direction or direction=="i")
for key,conn in ipairs(neighbourPositions) do
local meta=minetest.get_meta(conn)
local def=minetest.registered_nodes[minetest.get_node(conn).name]
local normalizedKey=industrialtest.api.normalizeSide(pos,key)
local powerOutput=(sourceDef.groups._industrialtest_cable or industrialtest.api.isPowerOutput(sourceMeta,normalizedKey))
local powerInput=(sourceDef.groups._industrialtest_cable or industrialtest.api.isPowerInput(sourceMeta,normalizedKey))
if def.groups._industrialtest_cable or industrialtest.api.hasPowerStorage(meta) then
local side=industrialtest.api.normalizeSide(conn,industrialtest.api.getOppositeSide(key))
if (powerOutput and directionInput and (def.groups._industrialtest_cable or industrialtest.api.isPowerInput(meta,side))) or ((def.groups._industrialtest_cable or industrialtest.api.isPowerOutput(meta,side)) and powerInput and directionOutput) then
table.insert(result,conn)
end
end
end
return result
end

237
api/power.lua Normal file
View File

@ -0,0 +1,237 @@
-- IndustrialTest
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local function createItemPowerText(itemstack)
local meta=itemstack:get_meta()
local powerCapacity=meta:get_int("industrialtest.powerCapacity")
local powerAmount=meta:get_int("industrialtest.powerAmount")
local lowerLimit=math.floor(powerCapacity*0.25)
local color=(powerAmount>lowerLimit and "#00FFFF" or "#FF0000")
return minetest.colorize(color,S("@1 / @2 EU",powerAmount,powerCapacity))
end
-- \brief Adds power storage to metadata
-- \param capacity How much EU item/node can store
-- \param flow How much EU can flow in or out item/node per industrialtest.updateDelay
-- \param ioConfig Input/Output configuration in following side order: -X, +X, -Y, +Y, -Z, +Z
-- a - bidirectional, i - input, o - output.
-- Instead of string containing IO mode for each side, ioConfig can hold a table for each side, containing
-- IO mode and flow override
-- \returns nil
function industrialtest.api.addPowerStorage(meta,capacity,flow,ioConfig)
meta:set_int("industrialtest.powerCapacity",capacity)
meta:set_int("industrialtest.powerFlow",flow)
meta:set_int("industrialtest.powerAmount",0)
meta:set_int("industrialtest.extendedIoConfig",type(ioConfig)~="string" and 1 or 0)
meta:set_string("industrialtest.ioConfig",type(ioConfig)=="string" and ioConfig or minetest.serialize(ioConfig))
end
-- \brief Checks if metadata contains power storage
-- \param meta MetaDataRef which should be checked
-- \returns true if metadata contains power storage, false otherwise
function industrialtest.api.hasPowerStorage(meta)
local values={"industrialtest.powerCapacity","industrialtest.powerFlow","industrialtest.powerAmount","industrialtest.ioConfig"}
for _,value in ipairs(values) do
if not meta:contains(value) then
return false
end
end
return true
end
-- \brief Checks if ioConfig from metadata is extended one. It exploits the fact that minetest.serialize returns Lua code
-- which returns table, hence it can check for return at the beginning of the string
-- \param meta MetaDataRef
-- \returns bool
function industrialtest.api.isExtendedIoConfig(meta)
return meta:get_int("industrialtest.extendedIoConfig")==1
end
-- \brief Returns ioConfig from metadata, deserializing it if it's extended one
-- \param meta MetaDataRef
-- \returns table or string
function industrialtest.api.getIoConfig(meta)
local ioConfig=meta:get_string("industrialtest.ioConfig")
return industrialtest.api.isExtendedIoConfig(meta) and minetest.deserialize(ioConfig) or ioConfig
end
-- \brief Changes node's power IO config. Function doesn't check if meta actually contains power storage.
-- \param meta MetaDataRef of node which power IO config should be changed
-- \param side Side number. See industrialtest.api.addPowerStorage to check order.
-- \param mode Side mode. See industrialtest.api.addPowerStorage for possible values.
-- \returns nil
function industrialtest.api.changeIoConfig(meta,side,mode)
local ioConfig=industrialtest.api.getIoConfig(meta)
if type(ioConfig)=="string" then
ioConfig=string.sub(ioConfig,1,side-1)..mode..string.sub(ioConfig,side+1)
meta:set_string("industrialtest.ioConfig",ioConfig)
else
ioConfig[side]=mode
meta:set_string("industrialtest.ioConfig",minetest.serialize(ioConfig))
end
end
-- \brief Returns power flow for side
-- \param meta MetaDataRef
-- \param side number Side number
-- \returns number
function industrialtest.api.getPowerFlowForSide(meta,side)
local ioConfig=industrialtest.api.getIoConfig(meta)
if type(ioConfig)=="string" then
return meta:get_int("industrialtest.powerFlow")
else
return ioConfig[side].flow
end
end
-- \brief Checks if provided side is power input
-- \param meta MetaDataRef of node
-- \param side Side number. See industrialtest.api.addPowerStorage to check order.
-- \returns true if provided side is power input, false otherwise
function industrialtest.api.isPowerInput(meta,side)
local ioConfig=industrialtest.api.getIoConfig(meta)
if type(ioConfig)=="string" then
local mode=string.sub(ioConfig,side,side)
return (mode=="i" or mode=="a")
else
return (ioConfig[side].mode=="i" or ioConfig[side].mode=="a")
end
end
-- \brief Checks if provided side is power output
-- \param meta MetaDataRef of node
-- \param side Side number. See industrialtest.api.addPowerStorage to check order.
-- \returns true if provided side is power output, false otherwise
function industrialtest.api.isPowerOutput(meta,side)
local ioConfig=industrialtest.api.getIoConfig(meta)
if type(ioConfig)=="string" then
local mode=string.sub(ioConfig,side,side)
return (mode=="o" or mode=="a")
else
return (ioConfig[side].mode=="o" or ioConfig[side].mode=="a")
end
end
-- \brief Checks if power storage is fully charged
-- \param meta MetaDataRef which should be checked
-- \returns true if power storage is fully charged, false otherwise
function industrialtest.api.isFullyCharged(meta)
return meta:get_int("industrialtest.powerAmount")>=meta:get_int("industrialtest.powerCapacity")
end
-- \brief Adds power to power storage. Function doesn't check if meta contains power storage so you must be sure that it does.
-- \param meta MetaDataRef to which power should be added
-- \param amount Amount of power to add
-- \returns How much of power was actually added
function industrialtest.api.addPower(meta,amount)
local powerAmount=meta:get_int("industrialtest.powerAmount")
local powerCapacity=meta:get_int("industrialtest.powerCapacity")
local prevPowerAmount=powerAmount
powerAmount=industrialtest.internal.clamp(powerAmount+amount,0,powerCapacity)
meta:set_int("industrialtest.powerAmount",powerAmount)
return powerAmount-prevPowerAmount
end
-- \brief Adds power to destination metadata while subtracting it from source metadata
-- \Param srcMeta MetaDataRef from which take power
-- \param destMeta MetaDataRef to which add power
-- \returns How much of power was actually transferred
function industrialtest.api.transferPower(srcMeta,destMeta,amount)
local currentFlow=math.min(srcMeta:get_int("industrialtest.powerAmount"),amount)
if currentFlow==0 then
return 0
end
local actualFlow=industrialtest.api.addPower(destMeta,currentFlow)
srcMeta:set_int("industrialtest.powerAmount",srcMeta:get_int("industrialtest.powerAmount")-actualFlow)
return actualFlow
end
-- \brief Updates itemstack description to show current power storage information, additionally updates item wear bar.
-- Function doesn't check if itemstack contains power storage so you should be sure that it does before calling this function
-- \param itemstack ItemStack which should be updated
-- \returns nil
function industrialtest.api.updateItemPowerText(itemstack)
local meta=itemstack:get_meta()
if industrialtest.mtgAvailable then
local def=minetest.registered_tools[itemstack:get_name()]
local desc=meta:contains("industrialtest.descriptionOverride") and meta:get_string("industrialtest.descriptionOverride") or def.description
local powerText=createItemPowerText(itemstack)
meta:set_string("description",string.format("%s\n%s",desc,powerText))
elseif industrialtest.mclAvailable then
tt.reload_itemstack_description(itemstack)
end
itemstack:set_wear(65535-meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")*65534)
end
-- \brief Adds power to itemstack. Function checks if itemstack has power storage.
-- \param itemstack ItemStack to which add power
-- \param amount How much power to add
-- \returns Amount of power added
function industrialtest.api.addPowerToItem(itemstack,amount)
local meta=itemstack:get_meta()
if not industrialtest.api.hasPowerStorage(meta) then
return 0
end
local added=industrialtest.api.addPower(meta,amount)
industrialtest.api.updateItemPowerText(itemstack)
return added
end
-- \brief Adds power to destination itemstack while subtracting it from source metadata
-- \param srcMeta MetaDataRef from which take power
-- \param itemstack ItemStack to which add power
-- \param amount number
-- \returns How much of power was actually transferred
function industrialtest.api.transferPowerToItem(srcMeta,itemstack,amount)
local currentFlow=math.min(srcMeta:get_int("industrialtest.powerAmount"),amount)
if currentFlow==0 then
return 0
end
local actualFlow=industrialtest.api.addPowerToItem(itemstack,currentFlow)
srcMeta:set_int("industrialtest.powerAmount",srcMeta:get_int("industrialtest.powerAmount")-actualFlow)
return actualFlow
end
-- \brief Adds power to destination metadata while subtracting it from source itemstack
-- \param srcItemstack ItemStack from which subtract power
-- \param meta MetaDataRef to which add power
-- \param amount How much power should be transferred
-- \returns How much of power was actually transferred
function industrialtest.api.transferPowerFromItem(srcItemstack,meta,amount)
local srcMeta=srcItemstack:get_meta()
local currentFlow=math.min(srcMeta:get_int("industrialtest.powerAmount"),amount)
if currentFlow==0 then
return 0
end
local actualFlow=industrialtest.api.addPower(meta,currentFlow)
industrialtest.api.addPowerToItem(srcItemstack,-actualFlow)
return actualFlow
end
if industrialtest.mclAvailable then
tt.register_snippet(function(itemstring,toolCapabilities,itemstack)
if not itemstack then
return nil
end
local meta=itemstack:get_meta()
if not industrialtest.api.hasPowerStorage(meta) then
return nil
end
return createItemPowerText(itemstack),false
end)
end

323
api/registration.lua Normal file
View File

@ -0,0 +1,323 @@
-- IndustrialTest
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
function industrialtest.api.addTag(name,tag)
if not industrialtest.api.tags[tag] then
industrialtest.api.tags[tag]={}
end
table.insert(industrialtest.api.tags[tag],name)
end
-- \brief Registers dust of certain resource
-- \param name Technical name of resource
-- \param displayName Display name of resource
-- \param resources List of tables with following keys: <output>, <recipe>, [count(1)]
-- <> - required, [] - optional, () - default value
-- \param color HTML color of dust
-- \param registerMaceratorRecipe If true macerator recipe for dust will be registered
-- \returns nil
function industrialtest.api.registerResourceDust(name,displayName,resources,color,registerMaceratorRecipe)
minetest.register_craftitem("industrialtest:"..name.."_dust",{
description=S(displayName.." Dust"),
inventory_image="industrialtest_dust.png",
color=color
})
if registerMaceratorRecipe then
for _,value in ipairs(resources) do
industrialtest.api.registerMaceratorRecipe({
output="industrialtest:"..name.."_dust "..(value.count or 1),
recipe=value.resource
})
end
end
end
-- \brief Registers plate of certain resource
-- \param name Technical name of resource
-- \param displayName Display name of resource
-- \param resources List of tables with following keys: <output>, <recipe>, [count(1)]
-- <> - required, [] - optional, () - default value
-- \param color HTML color of plate
-- \param registerCompressorRecipe If true compressor recipe for plate will be registered
-- \returns nil
function industrialtest.api.registerPlate(name,displayName,resources,color,registerCompressorRecipe)
minetest.register_craftitem("industrialtest:"..name,{
description=displayName,
inventory_image="industrialtest_plate.png",
inventory_overlay="industrialtest_plate_overlay.png",
color=color
})
if registerCompressorRecipe then
for _,value in ipairs(resources) do
industrialtest.api.registerCompressorRecipe({
output="industrialtest:"..name.." "..(value.count or 1),
recipe=value.resource
})
end
end
end
-- \brief Registers cell with certain fluid
-- \param name Technical name of cell
-- \param displayName Display name of cell
-- \param node Node which can be picked up with this cell
-- \returns nil
function industrialtest.api.registerStorageCell(name,displayName,node,modname,color)
color = color or "#ffffffff"
if not modname then
modname="industrialtest"
end
minetest.register_craftitem("industrialtest:"..name.."_cell",{
description=S(displayName.." Cell"),
inventory_image="industrialtest_cell_fluid.png",
inventory_overlay="industrialtest_cell_casing.png",
color=color,
on_place=function(itemstack,user,pointed)
if pointed.type~="node" or not user or not user:is_player() then
return nil
end
local node=minetest.get_node_or_nil(pointed.above)
local storage=industrialtest.api.getStorageCell("industrialtest:"..name.."_cell")
if storage.node then
if node.name~="air" and node.name~=storage.node then
return nil
end
minetest.set_node(pointed.above,{name=storage.node})
if itemstack:get_count()==1 then
itemstack:set_name("industrialtest:empty_cell")
else
local inv=user:get_inventory()
inv:add_item("main",ItemStack("industrialtest:empty_cell"))
itemstack:take_item()
end
return itemstack
end
return nil
end
})
industrialtest.api.storageCells["industrialtest:"..name.."_cell"]={
name="industrialtest:"..name.."_cell",
node=node
}
end
-- \brief Returns registred storage cell by name
-- \param name Storage cell name
-- \returns Table with following keys: name, node or nil in case of failure
function industrialtest.api.getStorageCell(name)
return industrialtest.api.storageCells[name]
end
-- \brief Returns registered storage cells by node
-- \param node Node ID
-- \returns Table with following keys: name, node or nil in case of failure
function industrialtest.api.getStorageCellByNode(node)
for _,value in pairs(industrialtest.api.storageCells) do
if value.node==node then
return value
end
end
return nil
end
-- \brief Registers macerator recipe
-- \param config Table with keys: <output>, <recipe>, [time(2)]
-- \returns nil
function industrialtest.api.registerMaceratorRecipe(config)
local definition={
output=config.output or "",
recipe=config.recipe or "",
time=config.time or 2
}
industrialtest.api.maceratorRecipes[definition.recipe]=definition
end
-- \brief Returns macerator recipe result
-- \param recipe String ID of resulting conten
-- \returns Table with following keys: output, recipe, time
function industrialtest.api.getMaceratorRecipeResult(recipe)
return industrialtest.api.maceratorRecipes[recipe]
end
-- \brief Registers compressor recipe
-- \param config Table with following keys: <output>, <recipe>, [time(2)], [count(1)]
-- \returns nil
function industrialtest.api.registerCompressorRecipe(config)
local definition={
output=config.output or "",
recipe=config.recipe or "",
time=config.time or 2,
count=config.count or 1
}
industrialtest.api.compressorRecipes[definition.recipe]=definition
end
-- \brief Returns macerator recipe result
-- \param recipe String ID of resulting conten
-- \returns Table with following keys: output, recipe, time
function industrialtest.api.getCompressorRecipeResult(recipe)
return industrialtest.api.compressorRecipes[recipe]
end
function industrialtest.api.registerExtractorRecipe(config)
local definition={
output=config.output or "",
recipe=config.recipe or "",
time=config.time or 2
}
industrialtest.api.extractorRecipes[definition.recipe]=definition
end
function industrialtest.api.getExtractorRecipeResult(recipe)
return industrialtest.api.extractorRecipes[recipe]
end
function industrialtest.api.registerCableFormerRecipe(config)
local definition={
output=config.output or "",
recipe=config.recipe or "",
time=config.time or 2
}
industrialtest.api.cableFormerRecipes[definition.recipe]=definition
end
function industrialtest.api.getCableFormerRecipeResult(recipe)
return industrialtest.api.cableFormerRecipes[recipe]
end
-- \brief Registers fuel that can be used in geothermal generator
-- \param fuel Table with following keys: <name>, <calorificValue>, <storageItems>
-- which is a table containing items which are tables with following keys: <name>, <leftover>
-- \returns nil
function industrialtest.api.registerGeothermalGeneratorFuel(config)
local definition={
name=config.name or "",
calorificValue=config.calorificValue or 0,
texture=config.texture or "industrialtest_gui_fluid_bg.png",
storageItems=config.storageItems or {}
}
industrialtest.api.geothermalGeneratorFuels[definition.name]=definition
end
-- \brief Returns generator fuel information
-- \param name Name of fuel
-- \returns Table with following keys: name, calorificValue, storageItems
function industrialtest.api.getGeothermalGeneratorFuel(name)
return industrialtest.api.geothermalGeneratorFuels[name]
end
-- \brief Returns generator fuel information by item name
-- \param name ID of item
-- \returns Table with following keys: name, calorificValue, storageItems or nil in case of failure
function industrialtest.api.getGeothermalGeneratorFuelByItem(name)
for _,value in pairs(industrialtest.api.geothermalGeneratorFuels) do
for _,item in ipairs(value.storageItems) do
if item.name==name then
return value
end
end
end
return nil
end
-- \brief Registers fuel that can be used in water mill
-- \param fuel Table with following keys: <name>, <calorificValue>, <storageItems>
-- which is a table containing items which are tables with following keys: <name>, <leftover>
-- \returns nil
function industrialtest.api.registerWaterMillFuel(config)
local definition={
name=config.name or "",
calorificValue=config.calorificValue or 0,
texture=config.texture or "industrialtest_gui_fluid_bg.png",
storageItems=config.storageItems or {}
}
industrialtest.api.waterMillFuels[definition.name]=definition
end
-- \brief Returns water mill fuel information
-- \param name Name of fuel
-- \returns Table with following keys: name, calorificValue, storageItems
function industrialtest.api.getWaterMillFuel(name)
return industrialtest.api.waterMillFuels[name]
end
-- \brief Returns water mill fuel information by item name
-- \param name ID of item
-- \returns Table with following keys: name, calorificValue, storageItems or nil in case of failure
function industrialtest.api.getWaterMillFuelByItem(name)
for _,value in pairs(industrialtest.api.waterMillFuels) do
for _,item in ipairs(value.storageItems) do
if item.name==name then
return value
end
end
end
return nil
end
-- \brief Registers Rotary Macerator recipe modifier
-- \param config table
-- \param omitPlaceholder bool, for internal use only
-- \returns nil
function industrialtest.api.registerRotaryMaceratorModifier(config,omitPlaceholder)
local definition={
name=config.name or "",
modifier=config.modifier or "",
output=config.output or "",
time=config.time or 2,
uses=config.uses or 1,
modifierLeftover=config.modifierLeftover
}
if not omitPlaceholder and not config.modifierLeftover and string.len(definition.modifier)>0 then
local delimiter,_=string.find(definition.modifier,":")
definition.stackLeftover="industrialtest:"..string.sub(definition.modifier,1,delimiter-1).."_"..string.sub(definition.modifier,delimiter+1,-1).."_leftover"
industrialtest.api.registerRotaryMaceratorModifier({
name=definition.name,
modifier=definition.stackLeftover,
output=definition.output,
time=definition.time,
uses=definition.uses
},true)
end
industrialtest.api.rotaryMaceratorModifiers[definition.name.." "..config.modifier]=definition
end
-- \brief Returns modified Rotary Macerator recipe by item and modifier
-- \param name string
-- \param modifier string
-- \returns table
function industrialtest.api.getRotaryMaceratorModifier(name,modifier)
return industrialtest.api.rotaryMaceratorModifiers[name.." "..modifier]
end
minetest.register_on_mods_loaded(function()
for _,def in pairs(industrialtest.api.rotaryMaceratorModifiers) do
if def.stackLeftover then
local leftoverDef=table.copy(minetest.registered_items[def.modifier])
leftoverDef.groups=leftoverDef.groups or {}
leftoverDef.groups.not_in_creative_inventory=1
if industrialtest.mclAvailable then
leftoverDef._doc_items_create_entry=false
end
-- Item name starts with : to prevent name checks, because it seems to fail in on_mods_loaded
minetest.register_craftitem(":"..def.stackLeftover,leftoverDef)
end
end
end)

49
api/side.lua Normal file
View File

@ -0,0 +1,49 @@
-- IndustrialTest
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
-- \brief Takes rotated node and side and outputs normalized side that can be used for ioConfig lookups
-- \param pos Vector with node position
-- \param side Node side. See industrialtest.api.addPowerStorage for possible values
-- \returns Normalized side or in case of failure side argument back
function industrialtest.api.normalizeSide(pos,side)
local node=minetest.get_node(pos)
-- FIXME: improve code quality there
local translation={
[0]={
1,2,3,4,5,6
},
[1]={
5,6,3,4,1,2
},
[2]={
2,1,3,4,6,5
},
[3]={
6,5,3,4,2,1
}
}
if node.param2>3 then
return side
end
return translation[node.param2][side]
end
-- \brief Returns opposite side of provided one
-- \param side Side number. See industrialtest.api.addPowerStorage for order
-- \returns Opposite side
function industrialtest.api.getOppositeSide(side)
return (side%2==0 and side-1 or side+1)
end

View File

@ -15,27 +15,43 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local cable={}
cable.onConstruct=function(pos)
industrialtest.Cable={}
function industrialtest.Cable.onConstruct(self,pos)
local connections=industrialtest.api.getConnections(pos)
for _,conn in ipairs(connections) do
local meta=minetest.get_meta(conn)
if industrialtest.api.isNetworkMaster(meta) then
industrialtest.api.createNetworkMapForNode(conn)
local networkNode=minetest.get_node(conn)
local def=minetest.registered_nodes[networkNode.name]
if def and def._industrialtest_self then
def._industrialtest_self:triggerIfNeeded(conn)
else
-- Support for bare definitions that don't use industrialtest pseudo-OOP
minetest.get_node_timer(conn):start(industrialtest.config.updateDelay)
end
else
local networks=industrialtest.api.isAttachedToNetwork(meta)
if networks then
for _,network in ipairs(networks) do
industrialtest.api.createNetworkMapForNode(network)
minetest.get_node_timer(network):start(industrialtest.updateDelay)
local networkNode=minetest.get_node(network)
local def=minetest.registered_nodes[networkNode.name]
if def and def._industrialtest_self then
def._industrialtest_self:triggerIfNeeded(network)
else
-- Support for bare definitions that don't use industrialtest pseudo-OOP
minetest.get_node_timer(network):start(industrialtest.config.updateDelay)
end
end
end
end
end
end
cable.onDestruct=function(pos)
function industrialtest.Cable.onDestruct(self,pos)
local meta=minetest.get_meta(pos)
local networks=industrialtest.api.isAttachedToNetwork(meta)
if networks then
@ -45,14 +61,16 @@ cable.onDestruct=function(pos)
end
end
local function registerCable(name,displayName,size,flow,registerInsulated)
local definition={
description=S(displayName.." Cable"),
inventory_image="industrialtest_"..name.."_cable_inv.png",
tiles={"industrialtest_"..name.."_cable.png"},
wield_image="industrialtest_"..name.."_cable_inv.png",
function industrialtest.Cable.createDefinitionTable(self,description,inventoryImage,tile,insulated)
local size=(insulated and self.size+0.02 or self.size)
local def={
description=description,
inventory_image=inventoryImage,
wield_image=inventoryImage,
tiles={tile},
paramtype="light",
sunlight_propagates=true,
use_texture_alpha=(self.transparent and "clip" or "opaque"),
drawtype="nodebox",
node_box={
type="connected",
@ -118,39 +136,67 @@ local function registerCable(name,displayName,size,flow,registerInsulated)
"group:_industrialtest_hasPowerOutput",
"group:_industrialtest_cable"
},
on_construct=cable.onConstruct,
on_destruct=cable.onDestruct,
_industrialtest_cableFlow=flow
on_construct=function(pos)
self:onConstruct(pos)
end,
on_destruct=function(pos)
self:onDestruct(pos)
end,
_industrialtest_cableFlow=self.flow
}
if industrialtest.mtgAvailable then
definition.groups={
def.groups={
cracky=1,
level=1,
oddly_breakable_by_hand=1
}
definition.sound=default.node_sound_metal_defaults()
def.sound=default.node_sound_metal_defaults()
elseif industrialtest.mclAvailable then
definition.groups={
def.groups={
handy=1,
pickaxey=1
}
definition._mcl_blast_resistance=1
definition._mcl_hardness=0.5
definition.sound=mcl_sounds.node_sound_metal_defaults()
def._mcl_blast_resistance=1
def._mcl_hardness=0.5
def.sound=mcl_sounds.node_sound_metal_defaults()
end
definition.groups._industrialtest_cable=1
minetest.register_node("industrialtest:"..name.."_cable",definition)
if registerInsulated then
definition=table.copy(definition)
definition.description=S("Insulated "..displayName.." Cable")
definition.inventory_image="industrialtest_insulated_"..name.."_cable_inv.png"
definition.tiles={"industrialtest_insulated_"..name.."_cable.png"}
definition.wield_image="industrialtest_insulated_"..name.."_cable_inv.png"
minetest.register_node("industrialtest:insulated_"..name.."_cable",definition)
def.groups._industrialtest_cable=1
if insulated then
def.groups._industrialtest_insulatedCable=1
end
return def
end
function industrialtest.Cable.register(self)
local def=self:createDefinitionTable(self.description,self.inventoryImage,self.tile,self.safe)
minetest.register_node(self.name,def)
if self.insulated then
def=self:createDefinitionTable(self.insulated.description,self.insulated.inventoryImage,self.insulated.tile,true)
minetest.register_node(self.insulated.name,def)
end
end
registerCable("tin","Tin",0.19,industrialtest.api.lvPowerFlow,true)
industrialtest.TinCable=table.copy(industrialtest.Cable)
industrialtest.internal.unpackTableInto(industrialtest.TinCable,{
name="industrialtest:tin_cable",
description=S("Tin Cable"),
inventoryImage="industrialtest_tin_cable_inv.png",
tile="industrialtest_tin_cable.png",
size=0.19,
flow=industrialtest.api.lvPowerFlow,
insulated={
name="industrialtest:insulated_tin_cable",
description=S("Insulated Tin Cable"),
inventoryImage="industrialtest_insulated_tin_cable_inv.png",
tile="industrialtest_insulated_tin_cable.png"
}
})
industrialtest.TinCable:register()
minetest.register_craft({
type="shaped",
output="industrialtest:tin_cable 6",
@ -158,6 +204,7 @@ minetest.register_craft({
{industrialtest.elementKeys.tinIngot,industrialtest.elementKeys.tinIngot,industrialtest.elementKeys.tinIngot}
}
})
minetest.register_craft({
type="shapeless",
output="industrialtest:insulated_tin_cable",
@ -166,6 +213,7 @@ minetest.register_craft({
industrialtest.elementKeys.rubber
}
})
minetest.register_craft({
type="shaped",
output="industrialtest:insulated_tin_cable 6",
@ -175,13 +223,31 @@ minetest.register_craft({
{industrialtest.elementKeys.rubber,industrialtest.elementKeys.rubber,industrialtest.elementKeys.rubber}
}
})
industrialtest.api.registerCableFormerRecipe({
output="industrialtest:tin_cable 12",
recipe=industrialtest.elementKeys.tinIngot,
time=1
})
registerCable("copper","Copper",0.15,industrialtest.api.mvPowerFlow,true)
industrialtest.CopperCable=table.copy(industrialtest.Cable)
industrialtest.internal.unpackTableInto(industrialtest.CopperCable,{
name="industrialtest:copper_cable",
description=S("Copper Cable"),
inventoryImage="industrialtest_copper_cable_inv.png",
tile="industrialtest_copper_cable.png",
size=0.15,
flow=industrialtest.api.mvPowerFlow,
insulated={
name="industrialtest:insulated_copper_cable",
description=S("Insulated Copper Cable"),
inventoryImage="industrialtest_insulated_copper_cable_inv.png",
tile="industrialtest_insulated_copper_cable.png"
}
})
industrialtest.CopperCable:register()
minetest.register_craft({
type="shaped",
output="industrialtest:copper_cable 6",
@ -189,6 +255,7 @@ minetest.register_craft({
{industrialtest.elementKeys.copperIngot,industrialtest.elementKeys.copperIngot,industrialtest.elementKeys.copperIngot}
}
})
minetest.register_craft({
type="shapeless",
output="industrialtest:insulated_copper_cable",
@ -197,6 +264,7 @@ minetest.register_craft({
industrialtest.elementKeys.rubber
}
})
minetest.register_craft({
type="shaped",
output="industrialtest:insulated_copper_cable 6",
@ -206,12 +274,30 @@ minetest.register_craft({
{industrialtest.elementKeys.rubber,industrialtest.elementKeys.rubber,industrialtest.elementKeys.rubber}
}
})
industrialtest.api.registerCableFormerRecipe({
output="industrialtest:copper_cable 12",
recipe=industrialtest.elementKeys.copperIngot
})
registerCable("gold","Gold",0.15,industrialtest.api.hvPowerFlow,true)
industrialtest.GoldCable=table.copy(industrialtest.Cable)
industrialtest.internal.unpackTableInto(industrialtest.GoldCable,{
name="industrialtest:gold_cable",
description=S("Gold Cable"),
inventoryImage="industrialtest_gold_cable_inv.png",
tile="industrialtest_gold_cable.png",
size=0.15,
flow=industrialtest.api.hvPowerFlow,
insulated={
name="industrialtest:insulated_gold_cable",
description=S("Insulated Gold Cable"),
inventoryImage="industrialtest_insulated_gold_cable_inv.png",
tile="industrialtest_insulated_gold_cable.png"
}
})
industrialtest.GoldCable:register()
minetest.register_craft({
type="shaped",
output="industrialtest:gold_cable 6",
@ -219,6 +305,7 @@ minetest.register_craft({
{industrialtest.elementKeys.goldIngot,industrialtest.elementKeys.goldIngot,industrialtest.elementKeys.goldIngot}
}
})
minetest.register_craft({
type="shapeless",
output="industrialtest:insulated_gold_cable",
@ -227,6 +314,7 @@ minetest.register_craft({
industrialtest.elementKeys.rubber
}
})
minetest.register_craft({
type="shaped",
output="industrialtest:insulated_gold_cable 6",
@ -236,12 +324,30 @@ minetest.register_craft({
{industrialtest.elementKeys.rubber,industrialtest.elementKeys.rubber,industrialtest.elementKeys.rubber}
}
})
industrialtest.api.registerCableFormerRecipe({
output="industrialtest:gold_cable 12",
recipe=industrialtest.elementKeys.goldIngot
})
registerCable("iron","Iron",0.15,industrialtest.api.evPowerFlow,true)
industrialtest.IronCable=table.copy(industrialtest.Cable)
industrialtest.internal.unpackTableInto(industrialtest.IronCable,{
name="industrialtest:iron_cable",
description=S("Iron Cable"),
inventoryImage="industrialtest_iron_cable_inv.png",
tile="industrialtest_iron_cable.png",
size=0.15,
flow=industrialtest.api.evPowerFlow,
insulated={
name="industrialtest:insulated_iron_cable",
description=S("Insulated Iron Cable"),
inventoryImage="industrialtest_insulated_iron_cable_inv.png",
tile="industrialtest_insulated_iron_cable.png"
}
})
industrialtest.IronCable:register()
minetest.register_craft({
type="shaped",
output="industrialtest:iron_cable 6",
@ -249,6 +355,7 @@ minetest.register_craft({
{"industrialtest:refined_iron_ingot","industrialtest:refined_iron_ingot","industrialtest:refined_iron_ingot"}
}
})
minetest.register_craft({
type="shapeless",
output="industrialtest:insulated_iron_cable",
@ -257,6 +364,7 @@ minetest.register_craft({
industrialtest.elementKeys.rubber
}
})
minetest.register_craft({
type="shaped",
output="industrialtest:insulated_iron_cable 6",
@ -266,13 +374,27 @@ minetest.register_craft({
{industrialtest.elementKeys.rubber,industrialtest.elementKeys.rubber,industrialtest.elementKeys.rubber}
}
})
industrialtest.api.registerCableFormerRecipe({
output="industrialtest:iron_cable 12",
recipe="industrialtest:refined_iron_ingot",
time=3
})
registerCable("glass_fibre","Glass Fibre",0.15,industrialtest.api.ivPowerFlow,false)
industrialtest.GlassFibreCable=table.copy(industrialtest.Cable)
industrialtest.internal.unpackTableInto(industrialtest.GlassFibreCable,{
name="industrialtest:glass_fibre_cable",
description=S("Glass Fibre Cable"),
inventoryImage="industrialtest_glass_fibre_cable_inv.png",
transparent=true,
tile="industrialtest_glass_fibre_cable.png",
safe=true,
size=0.12,
flow=industrialtest.api.ivPowerFlow
})
industrialtest.GlassFibreCable:register()
minetest.register_craft({
type="shaped",
output="industrialtest:glass_fibre_cable 4",
@ -283,3 +405,52 @@ minetest.register_craft({
}
})
-- TODO: Add glass fibre cable craft with silver ingot
if industrialtest.config.electrocution then
local electrocutionDelta=0
minetest.register_globalstep(function(dtime)
electrocutionDelta=electrocutionDelta+dtime
if electrocutionDelta<industrialtest.config.updateDelay then
return
end
electrocutionDelta=0
local offsets={
vector.new(0,0,0),
vector.new(-0.7,0,0),
vector.new(-0.7,1,0),
vector.new(0,1,0),
vector.new(0.7,0,0),
vector.new(0.7,1,0),
vector.new(0,0,-0.7),
vector.new(0,1,-0.7),
vector.new(0,0,0.7),
vector.new(0,1,0.7)
}
local players=minetest.get_connected_players()
for _,player in ipairs(players) do
local pos=player:get_pos()
for _,offset in ipairs(offsets) do
local nodePos=vector.add(pos,offset)
local node=minetest.get_node(nodePos)
local def=minetest.registered_nodes[node.name]
if def and def.groups and def.groups._industrialtest_cable and not def.groups._industrialtest_insulatedCable then
local meta=minetest.get_meta(pos)
local networks=industrialtest.api.isAttachedToNetwork(meta)
if networks then
local current=0
for _,network in ipairs(networks) do
current=current+industrialtest.api.getFlowingCurrent(network)
end
if current>0 then
local removed=math.ceil(current/500)
player:set_hp(player:get_hp()-removed,"electrocution")
break
end
end
end
end
end
end)
end

68
compat/logistica.lua Normal file
View File

@ -0,0 +1,68 @@
-- IndustrialTest
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
local oldInsertItemstackForRequester=logistica.insert_itemstack_for_requester
-- Logistica overrides
function logistica.insert_itemstack_for_requester(requesterPos,itemstack,limitByRequest)
local result=oldInsertItemstackForRequester(requesterPos, itemstack, limitByRequest)
local targetPos=logistica.get_requester_target(requesterPos)
local def=minetest.registered_nodes[minetest.get_node(targetPos).name]
if def._logistica_afterRequesterItemstackInsert then
def._logistica_afterRequesterItemstackInsert(targetPos)
end
return result
end
local onInjectorTimer=logistica.on_timer_powered(function(pos,elapsed)
local result=logistica.on_injector_timer(pos,elapsed)
local targetPos=logistica.get_injector_target(pos)
local def=minetest.registered_nodes[minetest.get_node(targetPos).name]
if def._logistica_afterInjectorItemstackTake then
def._logistica_afterInjectorItemstackTake(targetPos)
end
return result
end)
for _,name in ipairs(logistica.group_get_all_nodes_for_group("injectors")) do
local override={
on_timer=onInjectorTimer
}
minetest.override_item(name,override)
end
local function afterLogisticaAction(pos)
local def=minetest.registered_nodes[minetest.get_node(pos).name]
if def and def._industrialtest_self then
def._industrialtest_self:triggerIfNeeded(pos)
end
end
local function addLogisticaCompatibility(name)
local override={
_logistica_afterRequesterItemstackInsert=afterLogisticaAction,
_logistica_afterInjectorItemstackTake=afterLogisticaAction
}
minetest.override_item(name,override)
end
for _,name in ipairs(industrialtest.api.tags.usesTimer) do
addLogisticaCompatibility(name)
end

View File

@ -27,16 +27,15 @@ local override={
meta:set_int("maintainSpeed",1)
local def=minetest.registered_nodes[node.name]
def._industrialtest_updateFormspec(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
def._industrialtest_self:updateFormspec(pos)
def._industrialtest_self:trigger(pos)
end,
action_off=function(pos,node)
local meta=minetest.get_meta(pos)
meta:set_int("maintainSpeed",0)
local def=minetest.registered_nodes[node.name]
def._industrialtest_updateFormspec(pos)
def._industrialtest_self:updateFormspec(pos)
end
}
}
@ -69,13 +68,13 @@ override={
meta:set_int("stateChanged",1)
local def=minetest.registered_nodes[node.name]
def._industrialtest_updateFormspec(pos)
def._industrialtest_self:updateFormspec(pos)
if isChamber then
def._industrialtest_synchronizeToChamber(originalPos)
def._industrialtest_self:synchronizeToChamber(originalPos)
end
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
def._industrialtest_self:triggerIfNeeded(pos)
end,
action_off=function(pos,node)
local isChamber=node.name=="industrialtest:nuclear_reactor_chamber"
@ -107,10 +106,10 @@ override={
meta:set_int("stateChanged",1)
local def=minetest.registered_nodes[node.name]
def._industrialtest_updateFormspec(pos)
def._industrialtest_self:updateFormspec(pos)
if isChamber then
def._industrialtest_synchronizeToChamber(originalPos)
def._industrialtest_self:synchronizeToChamber(originalPos)
end
end
}

View File

@ -41,7 +41,10 @@ local function addPipeworksCompatibility(name,sides,inputInventory)
return nil
end
local result=inv:add_item(listname,stack)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
local def=minetest.registered_nodes[node.name]
if def and def._industrialtest_self then
def._industrialtest_self:triggerIfNeeded(pos)
end
return result
end,
can_insert=function(pos,node,stack,direction)
@ -53,6 +56,16 @@ local function addPipeworksCompatibility(name,sides,inputInventory)
end
return inv:room_for_item(listname,stack)
end,
remove_items=function(pos,node,stack,direction,count,listname)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:remove_item(listname,stack)
local def=minetest.registered_nodes[node.name]
if def and def._industrialtest_self then
def._industrialtest_self:triggerIfNeeded(pos)
end
return stack
end,
input_inventory=inputInventory,
connect_sides={
left=1,
@ -157,7 +170,8 @@ local override={
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local result=inv:add_item(listname,stack)
minetest.registered_nodes["industrialtest:nuclear_reactor"].on_metadata_inventory_put(pos)
industrialtest.Reactor.synchronizeChambers(pos)
industrialtest.Reactor:triggerIfNeeded(pos)
return result
end,
can_insert=function(pos,node,stack,direction)
@ -171,6 +185,14 @@ local override={
local inv=meta:get_inventory()
return inv:room_for_item(listname,stack)
end,
remove_items=function(pos,node,stack,direction,count,listname)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:remove_item(listname,stack)
industrialtest.Reactor.synchronizeChambers(pos)
industrialtest.Reactor:triggerIfNeeded(pos)
return stack
end,
input_inventory="fuel",
connect_sides={
left=1,
@ -207,10 +229,22 @@ override.tube.insert_object=function(pos,node,stack,direction)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local result=inv:add_item(listname,stack)
minetest.registered_nodes["industrialtest:nuclear_reactor_chamber"].on_metadata_inventory_put(pos)
industrialtest.Reactor:synchronizeToChamber(pos)
local reactorPos=minetest.deserialize(meta:get_string("reactor"))
industrialtest.Reactor:triggerIfNeeded(reactorPos)
return result
end
override.tube.remove_items=function(pos,node,stack,direction,count,listname)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:remove_item(listname,stack)
industrialtest.Reactor:synchronizeToChamber(pos)
local reactorPos=minetest.deserialize(meta:get_string("reactor"))
industrialtest.Reactor:triggerIfNeeded(reactorPos)
return stack
end
override.after_place_node_old=def.after_place_node
override.after_place_node=function(pos)
minetest.registered_nodes["industrialtest:nuclear_reactor_chamber"].after_place_node_old(pos)
@ -269,20 +303,21 @@ override={
if direction.y==1 then
listname="powerStorage"
elseif direction.y==-1 then
listname="fuel"
listname="src"
else
listname="target"
listname="dst"
end
local def=stack:get_definition()
if (listname=="powerStorage" and not industrialtest.api.hasPowerStorage(stack:get_meta())) or
(listname=="fuel" and (not def.groups or not def.groups._industrialtest_fuel)) or
(listname=="target" and (not def.groups or not def.groups._industrialtest_fueled)) then
(listname=="src" and (not def.groups or not def.groups._industrialtest_fuel)) or
(listname=="dst" and (not def.groups or not def.groups._industrialtest_fueled)) then
return nil
end
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local result=inv:add_item(listname,stack)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
local nodeDef=minetest.registered_nodes[node.name]
nodeDef._industrialtest_self:triggerIfNeeded(pos)
return result
end,
can_insert=function(pos,node,stack,direction)
@ -290,21 +325,28 @@ override={
if direction.y==1 then
listname="powerStorage"
elseif direction.y==-1 then
listname="fuel"
listname="src"
else
listname="target"
listname="dst"
end
local def=stack:get_definition()
if (listname=="powerStorage" and not industrialtest.api.hasPowerStorage(stack:get_meta())) or
(listname=="fuel" and (not def.groups or not def.groups._industrialtest_fuel)) or
(listname=="target" and (not def.groups or not def.groups._industrialtest_fueled)) then
(listname=="src" and (not def.groups or not def.groups._industrialtest_fuel)) or
(listname=="dst" and (not def.groups or not def.groups._industrialtest_fueled)) then
return false
end
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
return inv:room_for_item(listname,stack)
end,
input_inventory="target",
remove_items=function(pos,node,stack,direction,count,listname)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:remove_item(listname,stack)
industrialtest.CanningMachine:triggerIfNeeded(pos)
return stack
end,
input_inventory="dst",
connect_sides={
left=1,
right=1,
@ -344,7 +386,7 @@ addPipeworksCompatibility("industrialtest:induction_furnace",{
},"dst")
-- Simple electric item processors
for _,name in ipairs(industrialtest.internal.simpleElectricItemProcessors) do
for _,name in ipairs(industrialtest.api.tags.simpleElectricItemProcessor) do
addPipeworksCompatibility(name,{
{
y=1,

View File

@ -40,6 +40,7 @@ elseif industrialtest.mclAvailable then
industrialtest.mods.mclRubber=minetest.get_modpath("mcl_rubber")
end
industrialtest.mods.pipeworks=minetest.get_modpath("pipeworks")
industrialtest.mods.logistica=minetest.get_modpath("logistica")
industrialtest.mods.mesecons=minetest.get_modpath("mesecons")
if industrialtest.mtgAvailable and not industrialtest.mods._3dArmor then
@ -202,7 +203,7 @@ if industrialtest.mclAvailable then
minetest.register_tool("industrialtest:"..material.."_pickaxe",{
description=S(materialDisplayName.." Pickaxe"),
inventory_image="industrialtest_mcl_"..material.."_pickaxe.png",
groups={tool=1,pickaxe=1,dig_speed_class=config.digSpeedClass},
groups={tool=1,pickaxe=1,dig_speed_class=config.digSpeedClass,enchantability=config.enchantability},
tool_capabilities={
full_punch_interval=1,
max_drop_level=config.dropLevel,
@ -218,7 +219,7 @@ if industrialtest.mclAvailable then
minetest.register_tool("industrialtest:"..material.."_shovel",{
description=S(materialDisplayName.." Shovel"),
inventory_image="industrialtest_mcl_"..material.."_shovel.png",
groups={tool=1,shovel=1,dig_speed_class=config.digSpeedClass},
groups={tool=1,shovel=1,dig_speed_class=config.digSpeedClass,enchantability=config.enchantability},
tool_capabilities={
full_punch_interval=1,
max_drop_level=config.dropLevel,
@ -270,7 +271,7 @@ if industrialtest.mclAvailable then
minetest.register_tool("industrialtest:"..material.."_axe",{
description=S(materialDisplayName.." Axe"),
inventory_image="industrialtest_mcl_"..material.."_axe.png",
groups={tool=1,axe=1,dig_speed_class=config.digSpeedClass},
groups={tool=1,axe=1,dig_speed_class=config.digSpeedClass,enchantability=config.enchantability},
tool_capabilities={
full_punch_interval=1,
max_level_drop=config.levelDrop,
@ -287,7 +288,7 @@ if industrialtest.mclAvailable then
minetest.register_tool("industrialtest:"..material.."_sword",{
description=S(materialDisplayName.." Sword"),
inventory_image="industrialtest_mcl_"..material.."_sword.png",
groups={weapon=1,sword=1,dig_speed_class=config.digSpeedClass},
groups={weapon=1,sword=1,dig_speed_class=config.digSpeedClass,enchantability=config.enchantability},
tool_capabilities={
full_punch_interval=0.625,
max_drop_level=config.maxDropLevel,
@ -304,7 +305,7 @@ if industrialtest.mclAvailable then
minetest.register_tool("industrialtest:"..material.."_hoe",{
description=S(materialDisplayName.." Hoe"),
inventory_image="industrialtest_mcl_"..material.."_hoe.png",
groups={tool=1,hoe=1},
groups={tool=1,hoe=1,enchantability=config.enchantability},
tool_capabilities={
full_punch_interval=1,
damage_groups={fleshy=1}
@ -372,6 +373,7 @@ if industrialtest.mclAvailable then
cook_material=config.armorCookMaterial,
sound_equip=config.armorEquipSound,
sound_unequip=config.armorUnequipSound,
enchantability=config.enchantability,
textures={
head="industrialtest_mcl_"..material.."_helmet.png",
torso="industrialtest_mcl_"..material.."_chestplate.png",
@ -448,6 +450,7 @@ if industrialtest.mclAvailable then
industrialtest.elementKeys.stick="mcl_core:stick"
industrialtest.elementKeys.flint="mcl_core:flint"
industrialtest.elementKeys.snowball="mcl_throwing:snowball"
industrialtest.elementKeys.snowBlock="mcl_core:snowblock"
industrialtest.elementKeys.string="mcl_mobitems:string"
industrialtest.elementKeys.junglePlanks="mcl_core:junglewood"
industrialtest.elementKeys.wood="mcl_core:tree"
@ -503,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")
@ -575,7 +579,8 @@ if industrialtest.mclAvailable then
},
armorCookMaterial="industrialtest:bronze_nugget",
armorEquipSound="mcl_armor_equip_iron",
armorUnequipSound="mcl_armor_unequip_iron"
armorUnequipSound="mcl_armor_unequip_iron",
enchantability=15,
})
--register other blocks that are not availabe in MCL
@ -687,6 +692,7 @@ elseif industrialtest.mtgAvailable then
industrialtest.elementKeys.stick="default:stick"
industrialtest.elementKeys.flint="default:flint"
industrialtest.elementKeys.snowball="default:snow"
industrialtest.elementKeys.snowBlock="default:snowblock"
industrialtest.elementKeys.blueDye="dye:blue"
industrialtest.elementKeys.yellowDust="dye:yellow"
industrialtest.elementKeys.bucket="bucket:bucket_empty"
@ -735,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"

View File

@ -41,75 +41,6 @@ local colors={
coolant="#188676ff"
}
-- Power storage items
minetest.register_tool("industrialtest:re_battery",{
description=S("RE-Battery"),
inventory_image="industrialtest_re_battery.png",
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=7000,
_industrialtest_powerFlow=industrialtest.api.lvPowerFlow
})
minetest.register_craft({
type="shaped",
output="industrialtest:re_battery",
recipe={
{"","industrialtest:insulated_tin_cable",""},
{industrialtest.elementKeys.tinIngot,industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.tinIngot},
{industrialtest.elementKeys.tinIngot,industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.tinIngot}
}
})
minetest.register_tool("industrialtest:advanced_re_battery",{
description=S("Advanced RE-Battery"),
inventory_image="industrialtest_advanced_re_battery.png",
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=100000,
_industrialtest_powerFlow=industrialtest.api.mvPowerFlow
})
minetest.register_craft({
type="shaped",
output="industrialtest:advanced_re_battery",
recipe={
{"industrialtest:insulated_copper_cable",industrialtest.elementKeys.bronzeIngot,"industrialtest:insulated_copper_cable"},
{industrialtest.elementKeys.bronzeIngot,"industrialtest:sulfur_dust",industrialtest.elementKeys.bronzeIngot},
{industrialtest.elementKeys.bronzeIngot,"industrialtest:lead_dust",industrialtest.elementKeys.bronzeIngot}
}
})
minetest.register_tool("industrialtest:energy_crystal",{
description=S("Energy Crystal"),
inventory_image="industrialtest_energy_crystal.png",
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=100000,
_industrialtest_powerFlow=industrialtest.api.hvPowerFlow
})
minetest.register_craft({
type="shaped",
output="industrialtest:energy_crystal",
recipe={
{industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.powerCarrier},
{industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.diamond,industrialtest.elementKeys.powerCarrier},
{industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.powerCarrier}
}
})
minetest.register_tool("industrialtest:lapotron_crystal",{
description=S("Lapotron Crystal"),
inventory_image="industrialtest_lapotron_crystal.png",
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=1000000,
_industrialtest_powerFlow=industrialtest.api.evPowerFlow
})
minetest.register_craft({
type="shaped",
output="industrialtest:lapotron_crystal",
recipe={
{industrialtest.elementKeys.blueDye,"industrialtest:electronic_circuit",industrialtest.elementKeys.blueDye},
{industrialtest.elementKeys.blueDye,"industrialtest:energy_crystal",industrialtest.elementKeys.blueDye},
{industrialtest.elementKeys.blueDye,"industrialtest:electronic_circuit",industrialtest.elementKeys.blueDye}
}
})
-- Other resources
minetest.register_craftitem("industrialtest:refined_iron_ingot",{
description=S("Refined Iron Ingot"),
@ -871,38 +802,3 @@ industrialtest.api.registerCompressorRecipe({
recipe="industrialtest:plantball",
time=5
})
minetest.register_tool("industrialtest:fuel_can",{
description=S("Fuel Can"),
inventory_image="industrialtest_fuel_can.png",
groups={
_industrialtest_fueled=1,
_industrialtest_fuel=1,
_industrialtest_fluidStorage=1
},
_industrialtest_fluidCapacity=10000
})
minetest.register_craft({
type="shaped",
output="industrialtest:fuel_can",
recipe={
{"","industrialtest:tin_plate","industrialtest:tin_plate"},
{"industrialtest:tin_plate","","industrialtest:tin_plate"},
{"industrialtest:tin_plate","industrialtest:tin_plate","industrialtest:tin_plate"}
}
})
-- Item callbacks
minetest.register_on_player_inventory_action(function(player,action,inventory,info)
if action=="put" then
if industrialtest.api.preparePowerStorageItem(info.stack) or industrialtest.api.prepareToolItem(info.stack) or industrialtest.api.prepareFluidStorageItem(info.stack) then
inventory:set_stack(info.listname,info.index,info.stack)
end
end
end)
minetest.register_on_craft(function(itemstack)
if industrialtest.api.preparePowerStorageItem(itemstack) or industrialtest.api.prepareToolItem(itemstack) then
return
end
industrialtest.api.prepareFluidStorageItem(itemstack)
end)

View File

@ -14,25 +14,37 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
MODNAME="industrialtest"
local modpath=minetest.get_modpath(MODNAME)
local modpath=minetest.get_modpath("industrialtest")
-- table with global functions, variables etc
industrialtest={}
-- Initial constants
industrialtest.updateDelay=1 -- Note: Make this value smaller to make machines update more frequently (it may make server more laggy)
industrialtest.developerMode=true -- Enables additional utils useful when developing mod
-- Settings
industrialtest.config={
updateDelay=tonumber(minetest.settings:get("industrialtest.updateDelay") or "1"),
electrocution=minetest.settings:get_bool("industrialtest.electrocution",true),
developerMode=minetest.settings:get_bool("industrialtest.developerMode",false)
}
-- Others
industrialtest.random=PseudoRandom(os.time())
-- load other lua files
dofile(modpath.."/compatibility.lua")
dofile(modpath.."/api.lua")
dofile(modpath.."/minerals.lua")
dofile(modpath.."/machines/common.lua")
dofile(modpath.."/api/common.lua")
dofile(modpath.."/api/fluid.lua")
dofile(modpath.."/api/network.lua")
dofile(modpath.."/api/power.lua")
dofile(modpath.."/api/registration.lua")
dofile(modpath.."/api/side.lua")
dofile(modpath.."/machines/machine.lua")
dofile(modpath.."/machines/activated_machine.lua")
dofile(modpath.."/machines/electric_machine.lua")
dofile(modpath.."/machines/activated_electric_machine.lua")
dofile(modpath.."/machines/simple_electric_item_processor.lua")
dofile(modpath.."/machines/canning_machine.lua")
dofile(modpath.."/machines/chargepad.lua")
dofile(modpath.."/machines/compressor.lua")
@ -45,6 +57,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")
@ -55,14 +68,26 @@ dofile(modpath.."/machines/solar_panel_generator.lua")
dofile(modpath.."/machines/wind_mill.lua")
dofile(modpath.."/tools/common.lua")
dofile(modpath.."/tools/item.lua")
dofile(modpath.."/tools/electric_item.lua")
dofile(modpath.."/tools/electric_armor.lua")
dofile(modpath.."/tools/fluid_container_item.lua")
dofile(modpath.."/tools/tool.lua")
dofile(modpath.."/tools/gear_tool.lua")
dofile(modpath.."/tools/electric_tool.lua")
dofile(modpath.."/tools/activated_electric_tool.lua")
dofile(modpath.."/tools/electric_gear_tool.lua")
dofile(modpath.."/tools/batpack.lua")
dofile(modpath.."/tools/electric_chainsaw.lua")
dofile(modpath.."/tools/electric_drill.lua")
dofile(modpath.."/tools/electric_hoe.lua")
dofile(modpath.."/tools/electric_saber.lua")
dofile(modpath.."/tools/fluid_storage.lua")
dofile(modpath.."/tools/jetpack.lua")
dofile(modpath.."/tools/mining_laser.lua")
dofile(modpath.."/tools/nano_suit.lua")
dofile(modpath.."/tools/power_storage.lua")
dofile(modpath.."/tools/scanner.lua")
dofile(modpath.."/tools/solar_helmet.lua")
dofile(modpath.."/tools/static_boots.lua")
dofile(modpath.."/tools/treetap.lua")
@ -72,7 +97,7 @@ dofile(modpath.."/tools/wrench.lua")
dofile(modpath.."/upgrades.lua")
dofile(modpath.."/craftitems.lua")
dofile(modpath.."/nodes.lua")
if industrialtest.developerMode then
if industrialtest.config.developerMode then
dofile(modpath.."/utils.lua")
end
dofile(modpath.."/cables.lua")
@ -84,6 +109,9 @@ dofile(modpath.."/crafts.lua")
if industrialtest.mods.pipeworks then
dofile(modpath.."/compat/pipeworks.lua")
end
if industrialtest.mods.logistica then
dofile(modpath.."/compat/logistica.lua")
end
if industrialtest.mods.mesecons then
dofile(modpath.."/compat/mesecons.lua")
end

View File

@ -0,0 +1,44 @@
-- IndustrialTest
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
industrialtest.ActivatedElectricMachine=table.copy(industrialtest.ElectricMachine)
-- Forward methods from ActivatedMachine
industrialtest.internal.unpackTableInto(industrialtest.ActivatedElectricMachine,{
canUpdate=industrialtest.ActivatedMachine.canUpdate,
register=industrialtest.ActivatedMachine.register,
createDefinitionTable=industrialtest.ActivatedMachine.createDefinitionTable,
createActiveDefinitionTable=industrialtest.ActivatedMachine.createActiveDefinitionTable,
activate=industrialtest.ActivatedMachine.activate,
deactivate=industrialtest.ActivatedMachine.deactivate,
shouldActivate=industrialtest.ActivatedMachine.shouldActivate,
shouldDeactivate=industrialtest.ActivatedMachine.shouldDeactivate,
afterActivation=industrialtest.ActivatedMachine.afterActivation,
afterDeactivation=industrialtest.ActivatedMachine.afterDeactivation
})
function industrialtest.ActivatedElectricMachine.onTimer(self,pos,elapsed)
local result=self:powerExchange(pos)
local result2=industrialtest.ActivatedMachine.onTimer(self,pos,elapsed)
return result or result2
end
function industrialtest.ActivatedElectricMachine.activeOnTimer(self,pos,elapsed)
local result=self:powerExchange(pos)
local result2=industrialtest.ActivatedMachine.activeOnTimer(self,pos,elapsed)
return result or result2
end

View File

@ -0,0 +1,114 @@
-- IndustrialTest
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
industrialtest.ActivatedMachine=table.copy(industrialtest.Machine)
function industrialtest.ActivatedMachine.canUpdate(self,pos)
return self:shouldActivate(pos)
end
function industrialtest.ActivatedMachine.onTimer(self,pos,elapsed)
local result=industrialtest.Machine.onTimer(self,pos,elapsed)
if self:shouldActivate(pos) then
self:activate(pos)
return false
end
return result
end
function industrialtest.ActivatedMachine.register(self)
industrialtest.Machine.register(self)
local def=self:createActiveDefinitionTable()
minetest.register_node(self.name.."_active",def)
end
function industrialtest.ActivatedMachine.createActiveDefinitionTable(self)
local def=self:createDefinitionTable()
def.description=nil
def.drop=def.drop or self.name
if self.active then
def.tiles=self.active.tiles or def.tiles
def.light_source=self.active.lightSource
end
def.on_timer=function(pos,elapsed)
return self:activeOnTimer(pos,elapsed)
end
if industrialtest.mclAvailable then
def.groups.not_in_creative_inventory=1
def._doc_items_create_entry=false
end
return def
end
function industrialtest.ActivatedMachine.activate(self,pos)
minetest.swap_node(pos,{
name=self.name.."_active",
param2=minetest.get_node(pos).param2
})
self:afterActivation(pos)
minetest.get_node_timer(pos):start(industrialtest.config.updateDelay)
end
function industrialtest.ActivatedMachine.deactivate(self,pos)
minetest.swap_node(pos,{
name=self.name,
param2=minetest.get_node(pos).param2
})
self:afterDeactivation(pos)
minetest.get_node_timer(pos):start(industrialtest.config.updateDelay)
end
function industrialtest.ActivatedMachine.shouldActivate(self,pos)
return false
end
function industrialtest.ActivatedMachine.shouldDeactivate(self,pos)
return false
end
function industrialtest.ActivatedMachine.afterActivation(self,pos)
end
function industrialtest.ActivatedMachine.afterDeactivation(self,pos)
end
function industrialtest.ActivatedMachine.activeOnTimer(self,pos,elapsed)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local shouldUpdateFormspec=false
if self:shouldDeactivate(pos) then
self:deactivate(pos)
return false
end
if self.activeUpdate then
shouldUpdateFormspec=self:activeUpdate(pos,elapsed,meta,inv)
end
if shouldUpdateFormspec then
self:updateFormspec(pos)
end
return true
end

View File

@ -15,18 +15,55 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.internal.registerSimpleElectricItemProcessor({
name="cable_former",
displayName=S("Cable Former"),
customFrontTexture=true,
industrialtest.CableFormer=table.copy(industrialtest.SimpleElectricItemProcessor)
industrialtest.internal.unpackTableInto(industrialtest.CableFormer,{
name="industrialtest:cable_former",
description=S("Cable Former"),
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_cable_former_front.png"
},
requiresWrench=true,
active={
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_cable_former_front_active.png"
}
},
capacity=1400,
flow=industrialtest.api.lvPowerFlow,
opPower=80,
method="industrialtest.cable_forming",
efficiency=1
})
function industrialtest.CableFormer.getCraftResult(self,itemstack)
local output=industrialtest.api.getCableFormerRecipeResult(itemstack:get_name())
if not output then
return {
item=ItemStack(),
time=0,
src=itemstack
}
end
local srcAfter=ItemStack(itemstack:get_name())
srcAfter:set_count(itemstack:get_count()-1)
return {
item=ItemStack(output.output),
time=output.time,
src=srcAfter
}
end
industrialtest.CableFormer:register()
minetest.register_craft({
type="shaped",
output="industrialtest:cable_former",

View File

@ -15,15 +15,69 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local canningMachine={}
industrialtest.CanningMachine=table.copy(industrialtest.ActivatedElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.CanningMachine,{
name="industrialtest:canning_machine",
description=S("Canning Machine"),
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_canning_machine_front.png"
},
sounds="metal",
facedir=true,
storageLists={
"src",
"dst",
"leftover",
"upgrades",
"powerStorage"
},
powerLists={
{
list="powerStorage",
direction="i"
}
},
active={
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_canning_machine_front_active.png"
}
},
capacity=industrialtest.api.lvPowerFlow*2,
flow=industrialtest.api.lvPowerFlow,
ioConfig="iiiiii",
requiresWrench=true,
hasPowerInput=true,
_opPower=200,
_canningTime=5
})
canningMachine.opPower=200
canningMachine.canningTime=5
function industrialtest.CanningMachine.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("src",1)
inv:set_size("dst",1)
inv:set_size("leftover",1)
inv:set_size("powerStorage",1)
inv:set_size("upgrades",4)
meta:set_float("srcTime",0)
industrialtest.ActivatedElectricMachine.onConstruct(self,pos)
end
canningMachine.getFormspec=function(pos)
function industrialtest.CanningMachine.getFormspec(self,pos)
local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local powerPercent=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")*100
local srcPercent=meta:get_float("srcTime")/canningMachine.canningTime*100
local srcPercent=meta:get_float("srcTime")/self._canningTime*100
local formspec={
"list[context;src;3.4,1.8;1,1]",
industrialtest.internal.getItemSlotBg(3.4,1.8,1,1),
@ -42,44 +96,10 @@ canningMachine.getFormspec=function(pos)
"listring[context;src]",
"listring[context;dst]"
}
return table.concat(formspec,"")
return parentFormspec..table.concat(formspec,"")
end
canningMachine.onConstruct=function(pos,meta,inv)
inv:set_size("src",1)
inv:set_size("dst",1)
inv:set_size("leftover",1)
inv:set_size("powerStorage",1)
inv:set_size("upgrades",4)
meta:set_float("srcTime",0)
end
canningMachine.onTimer=function(pos,elapsed,meta,inv)
local shouldRerunTimer=false
local shouldUpdateFormspec=false
local fuelSlot=inv:get_stack("src",1)
local targetSlot=inv:get_stack("dst",1)
local leftoverSlot=inv:get_stack("leftover",1)
local powerStorageSlot=inv:get_stack("powerStorage",1)
local targetMeta=targetSlot:get_meta()
shouldRerunTimer,shouldUpdateFormspec=industrialtest.internal.chargeFromPowerStorageItem(meta,inv)
local def=fuelSlot:get_definition()
if not fuelSlot:is_empty() and not targetSlot:is_empty() and meta:get_int("industrialtest.powerAmount")>=canningMachine.opPower and (not def._industrialtest_emptyVariant or leftoverSlot:item_fits(ItemStack(def._industrialtest_emptyVariant))) and
(not industrialtest.api.itemHasFluidStorage(fuelSlot) or fuelSlot:get_meta():get_int("industrialtest.fluidAmount")>0) and targetMeta:get_int("industrialtest.fluidAmount")<targetMeta:get_int("industrialtest.fluidCapacity") then
minetest.swap_node(pos,{
name="industrialtest:canning_machine_active",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false,shouldUpdateFormspec
end
return shouldRerunTimer,true
end
canningMachine.allowMetadataInventoryMove=function(pos,fromList,fromIndex,toList,count)
function industrialtest.CanningMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
if toList=="src" then
local inv=minetest.get_meta(pos):get_inventory()
local itemstack=inv:get_stack(fromList,fromIndex)
@ -92,10 +112,13 @@ canningMachine.allowMetadataInventoryMove=function(pos,fromList,fromIndex,toList
local def=itemstack:get_definition()
return (def.groups and def.groups._industrialtest_fueled) and count or 0
end
return count
if toList=="leftover" then
return 0
end
return math.min(count,industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count))
end
canningMachine.allowMetadataInventoryPut=function(pos,listname,index,stack)
function industrialtest.CanningMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
if listname=="src" then
local def=stack:get_definition()
return (def.groups and def.groups._industrialtest_fuel) and stack:get_count() or 0
@ -104,71 +127,91 @@ canningMachine.allowMetadataInventoryPut=function(pos,listname,index,stack)
local def=stack:get_definition()
return (def.groups and def.groups._industrialtest_fueled) and stack:get_count() or 0
end
return stack:get_count()
if listname=="leftover" then
return 0
end
return math.min(stack:get_count(),industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player))
end
canningMachine.allowMetadataInventoryTake=function(pos,listname,index,stack)
function industrialtest.CanningMachine.allowMetadataInventoryTake(self,pos,listname,index,stack,player)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local fuelSlot=inv:get_stack("src",1)
local targetSlot=inv:get_stack("dst",1)
if ((listname=="src" and stack:get_count()==fuelSlot:get_count()) or (listname=="dst" and stack:get_count()==targetSlot:get_count())) and meta:get_float("srcTime")>0 then
meta:set_float("srcTime",0)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
self:updateFormspec(pos)
end
return stack:get_count()
return industrialtest.ActivatedElectricMachine.allowMetadataInventoryTake(self,pos,listname,index,stack,player)
end
canningMachine.onMetadataInventoryPut=function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
canningMachine.onMetadataInventoryMove=function(pos,fromList,fromIndex,toList,toIndex,count)
function industrialtest.CanningMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
industrialtest.ActivatedElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local fuelSlot=inv:get_stack("src",1)
local targetSlot=inv:get_stack("dst",1)
if ((fromList=="src" and count==fuelSlot:get_count()) or (fromList=="dst" and count==targetSlot:get_count())) and meta:get_float("srcTime")>0 then
meta:set_float("srcTime",0)
meta:set_string("formspec",canningMachine.getFormspec(pos))
self:updateFormspec(pos)
end
end
canningMachine.activeOnTimer=function(pos,elapsed,meta,inv)
function industrialtest.CanningMachine.onMetadataInventoryPut(self,pos,listname,index,stack)
self:triggerIfNeeded(pos)
industrialtest.ActivatedElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack)
end
function industrialtest.CanningMachine.shouldActivate(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local fuelSlot=inv:get_stack("src",1)
local targetSlot=inv:get_stack("dst",1)
local leftoverSlot=inv:get_stack("leftover",1)
local powerStorageSlot=inv:get_stack("powerStorage",1)
local targetMeta=targetSlot:get_meta()
local def=fuelSlot:get_definition()
return not fuelSlot:is_empty() and not targetSlot:is_empty() and meta:get_int("industrialtest.powerAmount")>=self._opPower and (not def._industrialtest_emptyVariant or leftoverSlot:item_fits(ItemStack(def._industrialtest_emptyVariant))) and
(not industrialtest.api.itemHasFluidStorage(fuelSlot) or fuelSlot:get_meta():get_int("industrialtest.fluidAmount")>0) and targetMeta:get_int("industrialtest.fluidAmount")<targetMeta:get_int("industrialtest.fluidCapacity")
end
function industrialtest.CanningMachine.shouldDeactivate(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local fuelSlot=inv:get_stack("src",1)
local fuelDef=fuelSlot:get_definition()
local targetSlot=inv:get_stack("dst",1)
local targetMeta=targetSlot:get_meta()
local leftoverSlot=inv:get_stack("leftover",1)
return fuelSlot:is_empty() or targetSlot:is_empty() or meta:get_int("industrialtest.powerAmount")<self._opPower or
(industrialtest.api.itemHasFluidStorage(fuelSlot) and industrialtest.api.isItemFluidStorageEmpty(fuelSlot)) or
industrialtest.api.isItemFluidStorageFull(targetSlot) or
targetMeta:get_int("industrialtest.fluidCapacity")-targetMeta:get_int("industrialtest.fluidAmount")<(fuelDef._industrialtest_fuelAmount or 0) or
(fuelDef._industrialtest_emptyVariant and not leftoverSlot:item_fits(ItemStack(fuelDef._industrialtest_emptyVariant)))
end
function industrialtest.CanningMachine.afterDeactivation(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local targetSlot=inv:get_stack("dst",1)
if meta:get_int("industrialtest.powerAmount")>=self._opPower or industrialtest.api.isItemFluidStorageFull(targetSlot) then
meta:set_float("srcTime",0)
end
self:updateFormspec(pos)
end
function industrialtest.CanningMachine.activeUpdate(self,pos,elapsed,meta,inv)
local shouldUpdateFormspec=false
local fuelSlot=inv:get_stack("src",1)
local targetSlot=inv:get_stack("dst",1)
local powerStorageSlot=inv:get_stack("powerStorage",1)
shouldRerunTimer,shouldUpdateFormspec=industrialtest.internal.chargeFromPowerStorageItem(meta,inv)
if fuelSlot:is_empty() or targetSlot:is_empty() or meta:get_int("industrialtest.powerAmount")<canningMachine.opPower then
if meta:get_int("industrialtest.powerAmount")>=canningMachine.opPower then
meta:set_float("srcTime",0)
end
minetest.swap_node(pos,{
name="industrialtest:canning_machine",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false,true
end
local fuelMeta=fuelSlot:get_meta()
local targetMeta=targetSlot:get_meta()
if (industrialtest.api.itemHasFluidStorage(fuelSlot) and fuelMeta:get_int("industrialtest.fluidAmount")==0) or targetMeta:get_int("industrialtest.fluidAmount")==targetMeta:get_int("industrialtest.fluidCapacity") then
meta:set_float("srcTime",0)
minetest.swap_node(pos,{
name="industrialtest:canning_machine",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false,true
end
local srcTime=meta:get_float("srcTime")
srcTime=srcTime+elapsed*industrialtest.api.getMachineSpeed(meta)
if srcTime>=canningMachine.canningTime then
local srcTime=meta:get_float("srcTime")+elapsed*industrialtest.api.getMachineSpeed(meta)
if srcTime>=self._canningTime then
if industrialtest.api.itemHasFluidStorage(fuelSlot) then
industrialtest.api.transferFluidToItem(fuelSlot,targetSlot,fuelMeta:get_int("industrialtest.fluidAmount"))
inv:set_stack("src",1,fuelSlot)
@ -177,12 +220,7 @@ canningMachine.activeOnTimer=function(pos,elapsed,meta,inv)
local def=fuelSlot:get_definition()
local leftoverSlot=inv:get_stack("leftover",1)
if targetMeta:get_int("industrialtest.fluidCapacity")-targetMeta:get_int("industrialtest.fluidAmount")<def._industrialtest_fuelAmount or (def._industrialtest_emptyVariant and not leftoverSlot:item_fits(ItemStack(def._industrialtest_emptyVariant))) then
minetest.swap_node(pos,{
name="industrialtest:canning_machine",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false,shouldUpdateFormspec
return shouldUpdateFormspec
end
industrialtest.api.addFluidToItem(targetSlot,def._industrialtest_fuelAmount)
inv:set_stack("dst",1,targetSlot)
@ -195,57 +233,13 @@ canningMachine.activeOnTimer=function(pos,elapsed,meta,inv)
else
meta:set_float("srcTime",srcTime)
end
industrialtest.api.addPower(meta,-canningMachine.opPower)
industrialtest.api.addPower(meta,-self._opPower)
return true,true
return true
end
industrialtest.internal.registerMachine({
name="canning_machine",
displayName=S("Canning Machine"),
capacity=industrialtest.api.lvPowerFlow*2,
getFormspec=canningMachine.getFormspec,
flow=industrialtest.api.lvPowerFlow,
ioConfig="iiiiii",
requiresWrench=true,
registerActiveVariant=true,
sounds="metal",
powerSlots={"powerStorage"},
storageSlots={"src","dst","powerStorage","upgrades"},
groups={
_industrialtest_hasPowerInput=1
},
customKeys={
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_canning_machine_front.png"
},
paramtype2="facedir",
legacy_facedir_simple=true
},
activeCustomKeys={
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_canning_machine_front_active.png"
}
},
onConstruct=canningMachine.onConstruct,
onTimer=canningMachine.onTimer,
allowMetadataInventoryMove=canningMachine.allowMetadataInventoryMove,
allowMetadataInventoryPut=canningMachine.allowMetadataInventoryPut,
allowMetadataInventoryTake=canningMachine.allowMetadataInventoryTake,
onMetadataInventoryPut=canningMachine.onMetadataInventoryPut,
onMetadataInventoryMove=canningMachine.onMetadataInventoryMove,
activeOnTimer=canningMachine.activeOnTimer
})
industrialtest.CanningMachine:register()
minetest.register_craft({
type="shaped",
output="industrialtest:canning_machine",

View File

@ -15,11 +15,71 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local chargepad={}
industrialtest.internal.chargepads={}
industrialtest.Chargepad=table.copy(industrialtest.ActivatedElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.Chargepad,{
storageLists={
"charged",
"discharged"
},
powerLists={
{
list="charged",
direction="o"
},
{
list="discharged",
direction="i"
}
},
facedir=true,
ioConfig="iiiioi",
hasPowerInput=true,
hasPowerOutput=true
})
local function chargePlayer(meta,player,flow)
function industrialtest.Chargepad.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("charged",1)
inv:set_size("discharged",1)
meta:set_int("active",0)
industrialtest.ActivatedElectricMachine.onConstruct(self,pos)
end
function industrialtest.Chargepad.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,pos)
local charged=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")
local formspec={
"list[context;charged;1,2.5;1,1]",
industrialtest.internal.getItemSlotBg(1,2.5,1,1),
"label[0.9,3.9;"..S("Charge").."]",
"list[context;discharged;3,2.5;1,1]",
industrialtest.internal.getItemSlotBg(3,2.5,1,1),
"label[2.7,3.9;"..S("Discharge").."]",
self.createPowerIndicatorWidget(charged,9,1),
"listring[context;charged]",
"listring[context;discharged]"
}
return parentFormspec..table.concat(formspec,"")
end
function industrialtest.Chargepad.register(self)
industrialtest.ActivatedElectricMachine.register(self)
table.insert(industrialtest.internal.chargepads,self.name)
table.insert(industrialtest.internal.chargepads,self.name.."_active")
minetest.register_craft({
type="shaped",
output=self.name,
recipe={
{"industrialtest:electronic_circuit",industrialtest.elementKeys.stoneSlab,"industrialtest:electronic_circuit"},
{industrialtest.elementKeys.rubber,self._basePowerStorage,industrialtest.elementKeys.rubber}
}
})
end
function industrialtest.Chargepad.chargePlayer(meta,player,flow)
local inv
if industrialtest.mtgAvailable then
_,inv=armor:get_valid_player(player,"")
@ -68,31 +128,7 @@ local function chargePlayer(meta,player,flow)
return true
end
chargepad.getFormspec=function(pos)
local meta=minetest.get_meta(pos)
local charged=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")
local formspec={
"list[context;charged;1,2.5;1,1]",
industrialtest.internal.getItemSlotBg(1,2.5,1,1),
"label[0.9,3.9;"..S("Charge").."]",
"list[context;discharged;3,2.5;1,1]",
industrialtest.internal.getItemSlotBg(3,2.5,1,1),
"label[2.7,3.9;"..S("Discharge").."]",
"box[9,1;0.3,4.8;#202020]",
(charged>0 and "box[9,"..(1+4.8-(charged*4.8))..";0.3,"..(charged*4.8)..";#FF1010]" or ""),
"listring[context;charged]",
"listring[context;discharged]"
}
return table.concat(formspec,"")
end
chargepad.onConstruct=function(pos,meta,inv)
inv:set_size("charged",1)
inv:set_size("discharged",1)
meta:set_int("active",0)
end
chargepad.action=function(pos,node)
function industrialtest.Chargepad.action(self,pos,node)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local chargedSlot=inv:get_stack("charged",1)
@ -116,138 +152,149 @@ chargepad.action=function(pos,node)
for _,player in ipairs(players) do
if vector.in_area(player:get_pos(),p1,p2) then
playerFound=true
shouldUpdateFormspec=shouldUpdateFormspec or chargePlayer(meta,player,flow)
shouldUpdateFormspec=shouldUpdateFormspec or self.chargePlayer(meta,player,flow)
break
end
end
local active=meta:get_int("active")==1
if playerFound and not active then
minetest.swap_node(pos,{
name=node.name.."_active",
param2=node.param2
})
self:activate(pos)
meta:set_int("active",1)
elseif (not playerFound or meta:get_int("industrialtest.powerAmount")==0) and active then
local def=minetest.registered_nodes[node.name]
minetest.swap_node(pos,{
name=def._industrialtest_baseNodeName,
param2=node.param2
})
self:deactivate(pos)
meta:set_int("active",0)
end
if shouldUpdateFormspec then
local def=minetest.registered_nodes[node.name]
def._industrialtest_updateFormspec(pos)
self:updateFormspec(pos)
end
end
local function registerChargepad(config)
industrialtest.internal.registerMachine({
name=config.name,
displayName=config.displayName,
capacity=config.capacity,
flow=config.flow,
ioConfig="iiiioi",
sounds=config.sounds,
powerSlots={"charged","discharged"},
storageSlots={"charged","discharged"},
requiresWrench=config.requiresWrench,
registerActiveVariant=true,
groups={
_industrialtest_hasPowerOutput=1,
_industrialtest_hasPowerInput=1
},
customKeys={
industrialtest.BatboxChargepad=table.copy(industrialtest.Chargepad)
industrialtest.internal.unpackTableInto(industrialtest.BatboxChargepad,{
name="industrialtest:batbox_chargepad",
description=S("BatBox Chargepad"),
tiles={
config.machineBlockTexture.."^industrialtest_chargepad_top.png",
config.machineBlockTexture,
config.machineBlockTexture,
config.machineBlockTexture,
config.machineBlockTexture,
config.machineBlockTexture.."^"..config.frontTexture
"industrialtest_wood_machine_block.png^industrialtest_chargepad_top.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png^industrialtest_batbox_front.png"
},
paramtype2="facedir",
legacy_facedir_simple=true
},
activeCustomKeys={
sounds="wood",
active={
tiles={
config.machineBlockTexture.."^industrialtest_chargepad_top_active.png",
config.machineBlockTexture,
config.machineBlockTexture,
config.machineBlockTexture,
config.machineBlockTexture,
config.machineBlockTexture.."^"..config.frontTexture
},
_industrialtest_baseNodeName="industrialtest:"..config.name
},
getFormspec=chargepad.getFormspec,
onConstruct=chargepad.onConstruct
})
minetest.register_craft({
type="shaped",
output="industrialtest:"..config.name,
recipe={
{"industrialtest:electronic_circuit",industrialtest.elementKeys.stoneSlab,"industrialtest:electronic_circuit"},
{industrialtest.elementKeys.rubber,"industrialtest:"..config.basePowerStorage,industrialtest.elementKeys.rubber}
"industrialtest_wood_machine_block.png^industrialtest_chargepad_top_active.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png^industrialtest_batbox_front.png"
}
})
table.insert(industrialtest.internal.chargepads,"industrialtest:"..config.name)
table.insert(industrialtest.internal.chargepads,"industrialtest:"..config.name.."_active")
end
registerChargepad({
name="batbox_chargepad",
displayName=S("BatBox Chargepad"),
},
capacity=25000,
flow=industrialtest.api.lvPowerFlow,
sounds="wood",
machineBlockTexture="industrialtest_wood_machine_block.png",
frontTexture="industrialtest_batbox_front.png",
requiresWrench=false,
basePowerStorage="batbox"
_basePowerStorage="industrialtest:batbox"
})
industrialtest.BatboxChargepad:register()
registerChargepad({
name="cesu_chargepad",
displayName=S("CESU Chargepad"),
industrialtest.CESUChargepad=table.copy(industrialtest.Chargepad)
industrialtest.internal.unpackTableInto(industrialtest.CESUChargepad,{
name="industrialtest:cesu_chargepad",
description=S("CESU Chargepad"),
tiles={
"industrialtest_bronze_machine_block.png^industrialtest_chargepad_top.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png^industrialtest_cesu_front.png"
},
sounds="metal",
active={
tiles={
"industrialtest_bronze_machine_block.png^industrialtest_chargepad_top_active.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png^industrialtest_cesu_front.png"
}
},
capacity=400000,
flow=industrialtest.api.mvPowerFlow,
sounds="metal",
machineBlockTexture="industrialtest_bronze_machine_block.png",
frontTexture="industrialtest_cesu_front.png",
requiresWrench=false,
basePowerStorage="cesu"
_basePowerStorage="industrialtest:cesu"
})
industrialtest.CESUChargepad:register()
registerChargepad({
name="mfe_chargepad",
displayName=S("MFE Chargepad"),
industrialtest.MFEChargepad=table.copy(industrialtest.Chargepad)
industrialtest.internal.unpackTableInto(industrialtest.MFEChargepad,{
name="industrialtest:mfe_chargepad",
description=S("MFE Chargepad"),
tiles={
"industrialtest_machine_block.png^industrialtest_chargepad_top.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png^industrialtest_mfe_front.png"
},
sounds="metal",
requiresWrench=true,
active={
tiles={
"industrialtest_machine_block.png^industrialtest_chargepad_top_active.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png^industrialtest_mfe_front.png"
}
},
capacity=3000000,
flow=industrialtest.api.hvPowerFlow,
sounds="metal",
machineBlockTexture="industrialtest_machine_block.png",
frontTexture="industrialtest_mfe_front.png",
requiresWrench=true,
basePowerStorage="mfe"
_basePowerStorage="industrialtest:mfe"
})
industrialtest.MFEChargepad:register()
registerChargepad({
name="mfsu_chargepad",
displayName=S("MFSU Chargepad"),
industrialtest.MFSUChargepad=table.copy(industrialtest.Chargepad)
industrialtest.internal.unpackTableInto(industrialtest.MFSUChargepad,{
name="industrialtest:mfsu_chargepad",
description=S("MFSU Chargepad"),
tiles={
"industrialtest_advanced_machine_block.png^industrialtest_chargepad_top.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_mfsu_front.png"
},
sounds="metal",
requiresWrench=true,
active={
tiles={
"industrialtest_advanced_machine_block.png^industrialtest_chargepad_top_active.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_mfsu_front.png"
}
},
capacity=30000000,
flow=industrialtest.api.evPowerFlow,
sounds="metal",
machineBlockTexture="industrialtest_advanced_machine_block.png",
frontTexture="industrialtest_mfsu_front.png",
requiresWrench=true,
basePowerStorage="mfsu"
_basePowerStorage="industrialtest:mfsu"
})
industrialtest.MFSUChargepad:register()
minetest.register_abm({
label="Chargepad updating",
nodenames=industrialtest.internal.chargepads,
interval=industrialtest.updateDelay,
interval=industrialtest.config.updateDelay,
chance=1,
action=chargepad.action
action=function(pos,node)
local def=minetest.registered_nodes[node.name]
def._industrialtest_self:action(pos,node)
end
})

View File

@ -1,787 +0,0 @@
-- IndustrialTest
-- Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
local machine={}
local simpleElectricItemProcessor={}
industrialtest.internal.simpleElectricItemProcessors={}
industrialtest.internal.mclAfterDigNode=function(pos,oldmeta,lists)
-- Taken from https://git.minetest.land/MineClone2/MineClone2/src/branch/master/mods/ITEMS/mcl_furnaces/init.lua#L538
local meta=minetest.get_meta(pos)
local meta2=meta
meta:from_table(oldmeta)
local inv=meta:get_inventory()
for _,listname in ipairs(lists) do
local stack=inv:get_stack(listname,1)
if not stack:is_empty() then
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5}
minetest.add_item(p, stack)
end
end
meta:from_table(meta2:to_table())
end
industrialtest.internal.allowMoveToUpgradeSlot=function(pos,toIndex,stack)
local def=minetest.registered_items[stack:get_name()]
if not def or not def.groups or not def.groups._industrialtest_machineUpgrade then
return 0
end
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local targetSlot=inv:get_stack("upgrades",toIndex)
if not targetSlot:is_empty() then
return 0
end
return stack:get_count()
end
industrialtest.internal.chargeFromPowerStorageItem=function(meta,inv)
local shouldRerunTimer=false
local shouldUpdateFormspec=false
local powerStorageSlot=inv:get_stack("powerStorage",1)
if not powerStorageSlot:is_empty() then
local stackMeta=powerStorageSlot:get_meta()
if industrialtest.api.transferPower(stackMeta,meta,stackMeta:get_int("industrialtest.powerFlow"))>0 then
shouldUpdateFormspec=true
shouldRerunTimer=stackMeta:get_int("industrialtest.powerAmount")>0 and not industrialtest.api.isFullyCharged(meta)
industrialtest.api.updateItemPowerText(powerStorageSlot)
inv:set_stack("powerStorage",1,powerStorageSlot)
end
end
return shouldRerunTimer,shouldUpdateFormspec
end
machine.getFormspec=function(pos,config)
local formspec
if industrialtest.mtgAvailable then
formspec={
"formspec_version[4]",
"size[10.8,12]",
"label[0.5,0.5;"..config.displayName.."]",
"list[current_player;main;0.5,6.25;8,1]",
"list[current_player;main;0.5,7.5;8,3;8]",
"listring[current_player;main]",
(config.getFormspec and config.getFormspec(pos) or "")
}
elseif industrialtest.mclAvailable then
formspec={
"size[10.04,12]",
"label[0.25,0.25;"..config.displayName.."]",
"list[current_player;main;0.5,7;9,3;9]",
mcl_formspec.get_itemslot_bg(0.5,7,9,3),
"list[current_player;main;0.5,10.24;9,1]",
mcl_formspec.get_itemslot_bg(0.5,10.24,9,1),
"listring[current_player;main]",
(config.getFormspec and config.getFormspec(pos) or "")
}
end
return table.concat(formspec,"")
end
machine.onConstruct=function(pos,config)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
industrialtest.api.addPowerStorage(meta,config.capacity,config.flow,config.ioConfig)
if config.groups then
if config.groups._industrialtest_hasPowerInput then
local connections=industrialtest.api.getConnections(pos)
for _,conn in ipairs(connections) do
local connectionMeta=minetest.get_meta(conn)
if industrialtest.api.isNetworkMaster(connectionMeta) then
industrialtest.api.createNetworkMapForNode(conn)
minetest.get_node_timer(conn):start(industrialtest.updateDelay)
else
local def=minetest.registered_nodes[minetest.get_node(conn).name]
if def.groups._industrialtest_cable then
local networks=industrialtest.api.isAttachedToNetwork(connectionMeta)
if networks then
for _,network in ipairs(networks) do
industrialtest.api.createNetworkMapForNode(network)
minetest.get_node_timer(network):start(industrialtest.updateDelay)
end
end
end
end
end
end
if config.groups._industrialtest_hasPowerOutput then
meta:set_string("industrialtest.network",minetest.serialize(industrialtest.api.createNetworkMap(pos)))
end
end
if config.onConstruct then
config.onConstruct(pos,meta,inv)
end
if not config.withoutFormspec then
meta:set_string("formspec",machine.getFormspec(pos,config))
end
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
machine.onDestruct=function(pos,config)
local meta=minetest.get_meta(pos)
if industrialtest.api.isNetworkMaster(meta) then
local network=industrialtest.api.createNetworkMap(pos,true)
for _,endpoint in ipairs(network) do
local endpointMeta=minetest.get_meta(endpoint.position)
local networks=industrialtest.api.isAttachedToNetwork(endpointMeta)
for key,value in ipairs(networks) do
if value.x==pos.x and value.y==pos.y and value.z==pos.z then
table.remove(networks,key)
break
end
end
endpointMeta:set_string("industrialtest.networks",minetest.serialize(networks))
end
end
local networks=industrialtest.api.isAttachedToNetwork(meta)
if networks then
for _,network in ipairs(networks) do
industrialtest.api.removeNodeFromNetwork(network,pos)
end
end
if config.onDestruct then
config.onDestruct(pos)
end
end
machine.onTimer=function(pos,elapsed,config)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local shouldRerunTimer=false
local shouldUpdateFormspec=false
if config.onTimer then
shouldRerunTimer,shouldUpdateFormspec=config.onTimer(pos,elapsed,meta,inv)
end
local def=minetest.registered_nodes[minetest.get_node(pos).name]
if def.groups and def.groups._industrialtest_hasPowerInput and not industrialtest.api.isFullyCharged(meta) then
local networks=industrialtest.api.isAttachedToNetwork(meta)
if networks then
for _,network in ipairs(networks) do
minetest.get_node_timer(network):start(industrialtest.updateDelay)
end
end
end
if shouldUpdateFormspec then
machine.updateFormspec(pos,config)
end
return shouldRerunTimer
end
machine.allowMetadataInventoryMove=function(pos,fromList,fromIndex,toList,toIndex,count,config)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local movedItemStack=inv:get_stack(fromList,1)
if toList=="upgrades" then
return industrialtest.internal.allowMoveToUpgradeSlot(pos,toIndex,movedItemStack)
end
local found=false
if config.powerSlots then
for _,value in ipairs(config.powerSlots) do
if value==toList then
found=true
break
end
end
end
if found and not industrialtest.api.hasPowerStorage(movedItemStack:get_meta()) then
return 0
end
if config.allowMetadataInventoryMove then
return config.allowMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex,count)
end
return count
end
machine.allowMetadataInventoryPut=function(pos,listname,index,stack,player,config)
if listname=="upgrades" then
return industrialtest.internal.allowMoveToUpgradeSlot(pos,index,stack)
end
local found=false
if config.powerSlots then
for _,value in ipairs(config.powerSlots) do
if value==listname then
found=true
break
end
end
end
if found and not industrialtest.api.hasPowerStorage(stack:get_meta()) then
return 0
end
if config.allowMetadataInventoryPut then
return config.allowMetadataInventoryPut(pos,listname,index,stack,player)
end
return stack:get_count()
end
machine.allowMetadataInventoryTake=function(pos,listname,index,stack,player,config)
if config.allowMetadataInventoryTake then
return config.allowMetadataInventoryTake(pos,listname,index,stack,player)
end
return stack:get_count()
end
machine.onMetadataInventoryMove=function(pos,fromList,fromIndex,toList,toIndex,count)
if toList=="upgrades" then
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local stack=inv:get_stack(fromList,fromIndex)
industrialtest.internal.applyUpgrade(pos,meta,stack)
elseif fromList=="upgrades" then
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local stack=inv:get_stack(fromList,fromIndex)
industrialtest.internal.removeUpgrade(pos,meta,stack)
end
end
machine.onMetadataInventoryPut=function(pos,listname,index,stack)
if listname=="upgrades" then
local meta=minetest.get_meta(pos)
industrialtest.internal.applyUpgrade(pos,meta,stack)
end
end
machine.onMetadataInventoryTake=function(pos,listname,index,stack)
if listname=="upgrades" then
local meta=minetest.get_meta(pos)
industrialtest.internal.removeUpgrade(pos,meta,stack)
end
end
machine.updateFormspec=function(pos,config)
if config.withoutFormspec then
return
end
local meta=minetest.get_meta(pos)
meta:set_string("formspec",machine.getFormspec(pos,config))
end
function industrialtest.internal.registerMachine(config)
local definition={
description=config.displayName,
on_construct=function(pos)
machine.onConstruct(pos,config)
end,
on_destruct=function(pos)
machine.onDestruct(pos,config)
end,
on_timer=function(pos,elapsed)
local shouldRerunTimer,_=machine.onTimer(pos,elapsed,config)
return shouldRerunTimer
end,
allow_metadata_inventory_move=function(pos,fromList,fromIndex,toList,toIndex,count)
return machine.allowMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex,count,config)
end,
allow_metadata_inventory_put=function(pos,listname,index,stack,player)
return machine.allowMetadataInventoryPut(pos,listname,index,stack,player,config)
end,
allow_metadata_inventory_take=function(pos,listname,index,stack,player)
return machine.allowMetadataInventoryTake(pos,listname,index,stack,player,config)
end,
on_metadata_inventory_put=function(pos,listname,index,stack,player)
machine.onMetadataInventoryPut(pos,listname,index,stack)
if config.onMetadataInventoryPut then
config.onMetadataInventoryPut(pos,listname,index,stack,player)
end
end,
on_metadata_inventory_move=function(pos,fromList,fromIndex,toList,toIndex,count)
machine.onMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex)
if config.onMetadataInventoryPut then
config.onMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex,count)
end
end,
on_metadata_inventory_take=function(pos,listname,index,stack,player)
machine.onMetadataInventoryTake(pos,listname,index,stack)
if config.onMetadataInventoryTake then
config.onMetadataInventoryTake(pos,listname,index,stack,player)
end
end,
_industrialtest_updateFormspec=function(pos)
machine.updateFormspec(pos,config)
end,
_industrialtest_getFormspec=function(pos)
if config.withoutFormspec then
return ""
end
return machine.getFormspec(pos,config)
end
}
if industrialtest.mtgAvailable then
definition.groups={cracky=2}
if config.sounds=="metal" then
definition.sounds=default.node_sound_metal_defaults()
end
definition.can_dig=function(pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
for _,value in ipairs(config.storageSlots) do
if inv:get_stack(value,1):get_count()>0 then
return false
end
end
return true
end
elseif industrialtest.mclAvailable then
definition.after_dig_node=function(pos,oldnode,oldmeta)
industrialtest.internal.mclAfterDigNode(pos,oldmeta,config.storageSlots)
end
if config.sounds=="metal" then
definition.sounds=mcl_sounds.node_sound_metal_defaults()
end
definition.groups={
pickaxey=1,
container=2
}
definition._mcl_blast_resistance=3.5
definition._mcl_hardness=3.9
definition._mcl_hoppers_on_try_pull=function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack("dst", 1)
if not stack:is_empty() and hop_inv:room_for_item(hop_list, stack) then
return inv, "dst", 1
end
return nil, nil, nil
end
definition._mcl_hoppers_on_try_push=function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv, "src", mcl_util.select_stack(hop_inv, hop_list, inv, "src")
end
definition._mcl_hoppers_on_after_push=function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
end
definition.groups._industrialtest_wrenchUnmountable=1
if config.requiresWrench then
definition.drop="industrialtest:machine_block"
end
if config.customKeys then
for key,value in pairs(config.customKeys) do
definition[key]=value
end
end
if config.groups then
for key,value in pairs(config.groups) do
definition.groups[key]=value
end
end
minetest.register_node("industrialtest:"..config.name,definition)
if config.registerActiveVariant then
definition=table.copy(definition)
definition.description=nil
definition.on_timer=function(pos,elapsed)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local shouldRerunTimer=false
local shouldUpdateFormspec=false
if config.activeOnTimer then
shouldRerunTimer,shouldUpdateFormspec=config.activeOnTimer(pos,elapsed,meta,inv)
end
local def=minetest.registered_nodes[minetest.get_node(pos).name]
if def.groups and def.groups._industrialtest_hasPowerInput and not industrialtest.api.isFullyCharged(meta) then
local networks=industrialtest.api.isAttachedToNetwork(meta)
if networks then
for _,network in ipairs(networks) do
minetest.get_node_timer(network):start(industrialtest.updateDelay)
end
end
end
if shouldUpdateFormspec then
machine.updateFormspec(pos,config)
end
return shouldRerunTimer
end
if not definition.drop then
definition.drop="industrialtest:"..config.name
end
if config.activeCustomKeys then
for key,value in pairs(config.activeCustomKeys) do
definition[key]=value
end
end
if industrialtest.mclAvailable then
definition.groups.not_in_creative_inventory=1
definition._doc_items_create_entry=false
end
minetest.register_node("industrialtest:"..config.name.."_active",definition)
end
end
local function craftResultProxy(method,item)
if method=="cooking" then
local output,after=minetest.get_craft_result({
method=method,
width=1,
items={item}
})
return {
item=output.item,
time=output.time,
src=after.items[1]
}
elseif method=="industrialtest.macerating" then
local output=industrialtest.api.getMaceratorRecipeResult(item:get_name())
if not output then
return {
item=ItemStack(),
time=0,
src=item
}
end
local srcAfter=ItemStack(item:get_name())
srcAfter:set_count(item:get_count()-1)
return {
item=ItemStack(output.output),
time=output.time,
src=srcAfter
}
elseif method=="industrialtest.compressing" then
local output=industrialtest.api.getCompressorRecipeResult(item:get_name())
if not output or item:get_count()<output.count then
return {
item=ItemStack(),
time=0,
src=item
}
end
local srcAfter=ItemStack(item:get_name())
srcAfter:set_count(item:get_count()-output.count)
return {
item=ItemStack(output.output),
time=output.time,
src=srcAfter
}
elseif method=="industrialtest.extracting" then
local output=industrialtest.api.getExtractorRecipeResult(item:get_name())
if not output then
return {
item=ItemStack(),
time=0,
src=item
}
end
local srcAfter=ItemStack(item:get_name())
srcAfter:set_count(item:get_count()-1)
return {
item=ItemStack(output.output),
time=output.time,
src=srcAfter
}
elseif method=="industrialtest.recycling" then
local srcAfter=ItemStack(item:get_name())
srcAfter:set_count(item:get_count()-1)
return {
item=ItemStack(industrialtest.random:next(1,8)==1 and "industrialtest:scrap" or ""),
time=2,
src=srcAfter
}
elseif method=="industrialtest.cable_forming" then
local output=industrialtest.api.getCableFormerRecipeResult(item:get_name())
if not output then
return {
item=ItemStack(),
time=0,
src=item
}
end
local srcAfter=ItemStack(item:get_name())
srcAfter:set_count(item:get_count()-1)
return {
item=ItemStack(output.output),
time=output.time,
src=srcAfter
}
elseif method=="industrialtest.mass_fabricating" then
if item:get_count()<34 then
return {
item=ItemStack(),
time=0,
src=item
}
end
local srcAfter=ItemStack(item:get_name())
srcAfter:set_count(item:get_count()-34)
return {
item=ItemStack("industrialtest:uu_matter"),
time=15,
src=srcAfter
}
end
error("Unknown craft method passed to craftResultProxy")
end
simpleElectricItemProcessor.getFormspec=function(pos)
local meta=minetest.get_meta(pos)
local powerPercent=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")*100
local srcPercent=meta:get_float("srcTime")/meta:get_float("maxSrcTime")*100
local formspec={
"list[context;src;3.4,1.8;1,1]",
industrialtest.internal.getItemSlotBg(3.4,1.8,1,1),
(powerPercent>0 and "image[3.4,2.8;1,1;industrialtest_gui_electricity_bg.png^[lowpart:"..powerPercent..":industrialtest_gui_electricity_fg.png]"
or "image[3.4,2.8;1,1;industrialtest_gui_electricity_bg.png]"),
"list[context;powerStorage;3.4,3.9;1,1]",
industrialtest.internal.getItemSlotBg(3.4,3.9,1,1),
(srcPercent>0 and "image[4.9,2.8;1,1;gui_furnace_arrow_bg.png^[lowpart:"..srcPercent..":gui_furnace_arrow_fg.png^[transformR270]"
or "image[4.9,2.8;1,1;gui_furnace_arrow_bg.png^[transformR270]"),
"list[context;dst;6.4,2.8;1,1]",
industrialtest.internal.getItemSlotBg(6.4,2.8,1,1),
"list[context;upgrades;9,0.9;1,4]",
industrialtest.internal.getItemSlotBg(9,0.9,1,4),
"listring[context;src]",
"listring[context;dst]"
}
return table.concat(formspec,"")
end
simpleElectricItemProcessor.onPowerFlow=function(pos)
-- FIXME: this probably will require refactor so node timer won't be started
-- just to test if machine can process item
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
simpleElectricItemProcessor.onConstruct=function(pos,meta,inv)
inv:set_size("src",1)
inv:set_size("dst",1)
inv:set_size("powerStorage",1)
inv:set_size("upgrades",4)
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
end
simpleElectricItemProcessor.onTimer=function(pos,elapsed,meta,inv,config)
local srcSlot=inv:get_stack("src",1)
local powerStorageSlot=inv:get_stack("powerStorage",1)
local shouldUpdateFormspec=false
local shouldRerunTimer=false
local requiredPower=elapsed*config.opPower*industrialtest.api.getMachineSpeed(meta)
shouldRerunTimer,shouldUpdateFormspec=industrialtest.internal.chargeFromPowerStorageItem(meta,inv)
if srcSlot:get_count()>0 and meta:get_int("industrialtest.powerAmount")>=requiredPower then
local output=craftResultProxy(config.method,srcSlot)
if output.time>0 and inv:room_for_item("dst",output.item) then
if meta:get_float("maxSrcTime")<=0 then
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",output.time*config.efficiency)
end
minetest.swap_node(pos,{
name="industrialtest:"..config.name.."_active",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
end
return shouldRerunTimer,shouldUpdateFormspec
end
simpleElectricItemProcessor.allowMetadataInventoryMove=function(pos,fromList,fromIndex,toList,count)
if toList=="dst" then
return 0
elseif toList=="upgrades" then
-- TODO: Add support for upgrades when they will be added
return 0
end
return count
end
simpleElectricItemProcessor.allowMetadataInventoryPut=function(pos,listname,index,stack)
if listname=="dst" then
return 0
elseif listname=="src" then
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
if srcSlot:get_name()~=stack:get_name() then
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
end
elseif listname=="upgrades" then
--TODO: See allow_metadata_inventory_move
return 0
end
return stack:get_count()
end
simpleElectricItemProcessor.onMetadataInventoryPut=function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
simpleElectricItemProcessor.onMetadataInventoryMove=function(pos,fromList,fromIndex,toList,toIndex,count)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
if fromList=="src" and count==srcSlot:get_count() then
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
if meta:get_int("industrialtest.powerAmount")>0 then
meta:set_string("formspec",simpleElectricItemProcessor.getFormspec(pos))
end
elseif fromList=="dst" and dstSlot:get_free_space()>0 then
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
end
simpleElectricItemProcessor.onMetadataInventoryTake=function(pos,listname,index,stack)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
if listname=="src" and stack:get_count()==srcSlot:get_count() then
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
if meta:get_int("industrialtest.powerAmount")>0 then
meta:set_string("formspec",simpleElectricItemProcessor.getFormspec(pos))
end
elseif listname=="dst" and dstSlot:get_free_space()>0 then
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
end
simpleElectricItemProcessor.activeOnTimer=function(pos,elapsed,meta,inv,config)
local srcSlot=inv:get_stack("src",1)
local powerStorageSlot=inv:get_stack("powerStorage",1)
local shouldUpdateFormspec=false
local shouldRerunTimer=false
local requiredPower=elapsed*config.opPower*industrialtest.api.getMachineSpeed(meta)
shouldRerunTimer,shouldUpdateFormspec=industrialtest.internal.chargeFromPowerStorageItem(meta,inv)
if srcSlot:get_count()>0 and meta:get_float("maxSrcTime")<=0 and meta:get_int("industrialtest.powerAmount")>=requiredPower then
local output=craftResultProxy(config.method,srcSlot)
if output.time>0 and inv:room_for_item("dst",output.item) then
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",output.time*config.efficiency)
end
end
if srcSlot:get_count()==0 and meta:get_float("maxSrcTime")>0 then
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
shouldUpdateFormspec=true
end
if meta:get_float("maxSrcTime")>0 then
if meta:get_int("industrialtest.powerAmount")>=requiredPower then
meta:set_int("industrialtest.powerAmount",meta:get_int("industrialtest.powerAmount")-requiredPower)
meta:set_float("srcTime",meta:get_float("srcTime")+elapsed)
shouldRerunTimer=true
end
shouldUpdateFormspec=true
end
if meta:get_float("maxSrcTime")<=0 or meta:get_int("industrialtest.powerAmount")<requiredPower then
minetest.swap_node(pos,{
name="industrialtest:"..config.name,
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
if meta:get_float("srcTime")>=meta:get_float("maxSrcTime") then
local output=craftResultProxy(config.method,srcSlot)
local speed=industrialtest.api.getMachineSpeed(meta)
local usedItems=srcSlot:get_count()-output.src:get_count()
local multiplier=1
if srcSlot:get_count()>=speed*usedItems then
multiplier=speed
end
if output.item:get_count()>0 then
output.item:set_count(output.item:get_count()*multiplier)
inv:add_item("dst",output.item)
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
end
srcSlot:set_count(srcSlot:get_count()-multiplier*usedItems)
inv:set_stack("src",1,srcSlot)
end
return shouldRerunTimer,shouldUpdateFormspec
end
function industrialtest.internal.registerSimpleElectricItemProcessor(config)
local machineBlockTexture=config.machineBlockTexture or "industrialtest_machine_block.png"
industrialtest.internal.registerMachine({
name=config.name,
displayName=config.displayName,
capacity=config.capacity,
getFormspec=simpleElectricItemProcessor.getFormspec,
flow=config.flow,
ioConfig="iiiiii",
requiresWrench=config.requiresWrench,
registerActiveVariant=true,
sounds="metal",
powerSlots={"powerStorage"},
storageSlots={"src","dst","powerStorage","upgrades"},
groups={
_industrialtest_hasPowerInput=1
},
customKeys={
tiles={
machineBlockTexture..(config.customTopTexture and "^industrialtest_"..config.name.."_top.png" or ""),
machineBlockTexture..(config.customBottomTexture and "^industrialtest_"..config.name.."_bottom.png" or ""),
machineBlockTexture..(config.customRightTexture and "^industrialtest_"..config.name.."_right.png" or ""),
machineBlockTexture..(config.customLeftTexture and "^industrialtest_"..config.name.."_left.png" or ""),
machineBlockTexture..(config.customBackTexture and "^industrialtest_"..config.name.."_back.png" or ""),
machineBlockTexture..(config.customFrontTexture and "^industrialtest_"..config.name.."_front.png" or "")
},
paramtype2="facedir",
legacy_facedir_simple=true,
_industrialtest_onPowerFlow=simpleElectricItemProcessor.onPowerFlow
},
activeCustomKeys={
tiles={
machineBlockTexture..(config.customTopTexture and "^industrialtest_"..config.name.."_top_active.png" or ""),
machineBlockTexture..(config.customBottomTexture and "^industrialtest_"..config.name.."_bottom_active.png" or ""),
machineBlockTexture..(config.customRightTexture and "^industrialtest_"..config.name.."_right_active.png" or ""),
machineBlockTexture..(config.customLeftTexture and "^industrialtest_"..config.name.."_left_active.png" or ""),
machineBlockTexture..(config.customBackTexture and "^industrialtest_"..config.name.."_back_active.png" or ""),
machineBlockTexture..(config.customFrontTexture and "^industrialtest_"..config.name.."_front_active.png" or "")
}
},
onConstruct=simpleElectricItemProcessor.onConstruct,
onTimer=function(pos,elapsed,meta,inv)
return simpleElectricItemProcessor.onTimer(pos,elapsed,meta,inv,config)
end,
allowMetadataInventoryMove=simpleElectricItemProcessor.allowMetadataInventoryMove,
allowMetadataInventoryPut=simpleElectricItemProcessor.allowMetadataInventoryPut,
onMetadataInventoryPut=simpleElectricItemProcessor.onMetadataInventoryPut,
onMetadataInventoryMove=simpleElectricItemProcessor.onMetadataInventoryMove,
onMetadataInventoryTake=simpleElectricItemProcessor.onMetadataInventoryTake,
activeOnTimer=function(pos,elapsed,meta,inv)
return simpleElectricItemProcessor.activeOnTimer(pos,elapsed,meta,inv,config)
end
})
table.insert(industrialtest.internal.simpleElectricItemProcessors,"industrialtest:"..config.name)
end

View File

@ -15,18 +15,55 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.internal.registerSimpleElectricItemProcessor({
name="compressor",
displayName=S("Compressor"),
customFrontTexture=true,
industrialtest.Compressor=table.copy(industrialtest.SimpleElectricItemProcessor)
industrialtest.internal.unpackTableInto(industrialtest.Compressor,{
name="industrialtest:compressor",
description=S("Compressor"),
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_compressor_front.png"
},
requiresWrench=true,
active={
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_compressor_front_active.png"
}
},
capacity=1400,
flow=industrialtest.api.lvPowerFlow,
opPower=120,
method="industrialtest.compressing",
efficiency=1
})
function industrialtest.Compressor.getCraftResult(self,itemstack)
local output=industrialtest.api.getCompressorRecipeResult(itemstack:get_name())
if not output or itemstack:get_count()<output.count then
return {
item=ItemStack(),
time=0,
src=itemstack
}
end
local srcAfter=ItemStack(itemstack:get_name())
srcAfter:set_count(itemstack:get_count()-output.count)
return {
item=ItemStack(output.output),
time=output.time,
src=srcAfter
}
end
industrialtest.Compressor:register()
minetest.register_craft({
type="shaped",
output="industrialtest:compressor",

View File

@ -15,17 +15,49 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.internal.registerSimpleElectricItemProcessor({
name="electric_furnace",
displayName=S("Electric Furnace"),
customFrontTexture=true,
industrialtest.ElectricFurnace=table.copy(industrialtest.SimpleElectricItemProcessor)
industrialtest.internal.unpackTableInto(industrialtest.ElectricFurnace,{
name="industrialtest:electric_furnace",
description=S("Electric Furnace"),
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_electric_furnace_front.png"
},
active={
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_electric_furnace_front_active.png"
}
},
capacity=416,
flow=industrialtest.api.lvPowerFlow,
opPower=60,
method="cooking",
efficiency=0.5
})
function industrialtest.ElectricFurnace.getCraftResult(self,itemstack)
local output,after=minetest.get_craft_result({
method="cooking",
width=1,
items={itemstack}
})
return {
item=output.item,
time=output.time,
src=after.items[1]
}
end
industrialtest.ElectricFurnace:register()
minetest.register_craft({
type="shaped",
output="industrialtest:electric_furnace",

View File

@ -0,0 +1,243 @@
-- IndustrialTest
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
industrialtest.ElectricMachine=table.copy(industrialtest.Machine)
function industrialtest.ElectricMachine.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
industrialtest.api.addPowerStorage(meta,self.capacity,self.flow,self.ioConfig)
if self.hasPowerInput then
local connections=industrialtest.api.getConnections(pos)
for _,conn in ipairs(connections) do
local connectionMeta=minetest.get_meta(conn)
if industrialtest.api.isNetworkMaster(connectionMeta) then
industrialtest.api.createNetworkMapForNode(conn)
local def=minetest.get_node(conn)
if def and def._industrialtest_self then
def._industrialtest_self:flowPower(conn)
else
-- Support for bare definitions that don't use industrialtest pseudo-OOP
minetest.get_node_timer(conn):start(industrialtest.config.updateDelay)
end
else
local def=minetest.registered_nodes[minetest.get_node(conn).name]
if def.groups._industrialtest_cable then
local networks=industrialtest.api.isAttachedToNetwork(connectionMeta)
if networks then
for _,network in ipairs(networks) do
industrialtest.api.createNetworkMapForNode(network)
local def=minetest.registered_nodes[minetest.get_node(network).name]
if def and def._industrialtest_self then
def._industrialtest_self:flowPower(network)
else
-- Support for bare definitions that don't use industrialtest pseudo-OOP
minetest.get_node_timer(network):start(industrialtest.config.updateDelay)
end
end
end
end
end
end
end
if self.hasPowerOutput then
meta:set_string("industrialtest.network",minetest.serialize(industrialtest.api.createNetworkMap(pos)))
end
industrialtest.Machine.onConstruct(self,pos)
end
function industrialtest.ElectricMachine.onDestruct(self,pos)
local meta=minetest.get_meta(pos)
if industrialtest.api.isNetworkMaster(meta) then
local network=industrialtest.api.createNetworkMap(pos,true)
for _,endpoint in ipairs(network) do
local endpointMeta=minetest.get_meta(endpoint.position)
local networks=industrialtest.api.isAttachedToNetwork(endpointMeta)
for key,value in ipairs(networks) do
if value.x==pos.x and value.y==pos.y and value.z==pos.z then
table.remove(networks,key)
break
end
end
endpointMeta:set_string("industrialtest.networks",minetest.serialize(networks))
end
end
local networks=industrialtest.api.isAttachedToNetwork(meta)
if networks then
for _,network in ipairs(networks) do
industrialtest.api.removeNodeFromNetwork(network,pos)
end
end
-- don't call onDestruct from parent class because it doesn't do anything
end
function industrialtest.ElectricMachine.onTimer(self,pos,elapsed)
local result=industrialtest.Machine.onTimer(self,pos,elapsed)
local result2=self:powerExchange(pos)
return result or result2
end
function industrialtest.ElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
local found=false
if self.powerLists then
for _,value in ipairs(self.powerLists) do
if value.list==toList then
found=true
break
end
end
end
if found and not industrialtest.api.hasPowerStorage(movedItemStack:get_meta()) then
return 0
end
return industrialtest.Machine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
function industrialtest.ElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
local found=false
if self.powerLists then
for _,value in ipairs(self.powerLists) do
if value.list==listname then
found=true
break
end
end
end
if found and not industrialtest.api.hasPowerStorage(stack:get_meta()) then
return 0
end
return industrialtest.Machine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
end
function industrialtest.ElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
if self.powerLists then
for _,value in ipairs(self.powerLists) do
if value.list==toList then
self:trigger(pos)
break
end
end
end
industrialtest.Machine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
function industrialtest.ElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack)
if self.powerLists then
for _,value in ipairs(self.powerLists) do
if value.list==listname then
self:trigger(pos)
break
end
end
end
industrialtest.Machine.onMetadataInventoryPut(self,pos,listname,index,stack)
end
function industrialtest.ElectricMachine.flowPower(self,pos)
if not self.hasPowerOutput then
return
end
local meta=minetest.get_meta(pos)
if meta:get_int("industrialtest.powerAmount")<=0 then
return
end
local _,flowTransferred=industrialtest.api.powerFlow(pos)
if flowTransferred then
self:updateFormspec(pos)
end
self:triggerIfNeeded(pos)
end
function industrialtest.ElectricMachine.requestPower(self,pos)
local meta=minetest.get_meta(pos)
local networks=industrialtest.api.isAttachedToNetwork(meta)
if networks then
for _,network in ipairs(networks) do
local def=minetest.registered_nodes[minetest.get_node(network).name]
if def and def._industrialtest_self then
def._industrialtest_self:flowPower(network)
else
-- Support for bare definitions that don't use industrialtest pseudo-OOP
minetest.get_node_timer(network):start(industrialtest.config.updateDelay)
end
end
end
end
function industrialtest.ElectricMachine.powerExchange(self,pos)
local meta=minetest.get_meta(pos)
local shouldRerunTimer=false
if self.hasPowerInput and not industrialtest.api.isFullyCharged(meta) then
self:requestPower(pos)
shouldRerunTimer=shouldRerunTimer or not industrialtest.api.isFullyCharged(meta)
end
if self.hasPowerOutput and meta:get_int("industrialtest.powerAmount")>0 then
local spaceAvailable,flowTransferred=industrialtest.api.powerFlow(pos)
if flowTransferred then
self:updateFormspec(pos)
end
shouldRerunTimer=shouldRerunTimer or spaceAvailable
end
if self.powerLists then
local inv=meta:get_inventory()
local powerFlow=meta:get_int("industrialtest.powerFlow")
for _,listDesc in ipairs(self.powerLists) do
local slot=inv:get_stack(listDesc.list,1)
if slot:get_count()>0 then
if listDesc.direction=="o" then
if meta:get_int("industrialtest.powerAmount")<=0 then
break
end
if not industrialtest.api.isFullyCharged(slot:get_meta()) then
industrialtest.api.transferPowerToItem(meta,slot,powerFlow)
inv:set_stack(listDesc.list,1,slot)
self:updateFormspec(pos)
shouldRerunTimer=shouldRerunTimer or (not industrialtest.api.isFullyCharged(slot:get_meta()) and meta:get_int("industrialtest.powerAmount")>0)
end
elseif listDesc.direction=="i" then
if industrialtest.api.isFullyCharged(meta) then
break
end
local slotMeta=slot:get_meta()
if slotMeta:get_int("industrialtest.powerAmount")>0 then
industrialtest.api.transferPowerFromItem(slot,meta,powerFlow)
inv:set_stack(listDesc.list,1,slot)
self:updateFormspec(pos)
shouldRerunTimer=shouldRerunTimer or (not industrialtest.api.isFullyCharged(meta) and slotMeta:get_int("industrialtest.powerAmount")>0)
end
end
end
end
end
return shouldRerunTimer
end
function industrialtest.ElectricMachine.createPowerIndicatorWidget(charged,x,y)
return table.concat({
string.format("box[%f,%f;0.3,4.8;#202020]",x,y),
(charged>0 and string.format("box[%f,%f;0.3,%f;#FF1010]",x,y+4.8-(charged*4.8),charged*4.8) or ""),
},"")
end

View File

@ -15,18 +15,55 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.internal.registerSimpleElectricItemProcessor({
name="extractor",
displayName=S("Extractor"),
customFrontTexture=true,
industrialtest.Extractor=table.copy(industrialtest.SimpleElectricItemProcessor)
industrialtest.internal.unpackTableInto(industrialtest.Extractor,{
name="industrialtest:extractor",
description=S("Extractor"),
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_extractor_front.png"
},
requiresWrench=true,
capacity=900,
active={
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_extractor_front_active.png"
}
},
capacity=1000,
flow=industrialtest.api.lvPowerFlow,
opPower=100,
method="industrialtest.extracting",
efficiency=1
})
function industrialtest.Extractor.getCraftResult(self,itemstack)
local output=industrialtest.api.getExtractorRecipeResult(itemstack:get_name())
if not output then
return {
item=ItemStack(),
time=0,
src=itemstack
}
end
local srcAfter=ItemStack(itemstack:get_name())
srcAfter:set_count(itemstack:get_count()-1)
return {
item=ItemStack(output.output),
time=output.time,
src=srcAfter
}
end
industrialtest.Extractor:register()
minetest.register_craft({
type="shaped",
output="industrialtest:extractor",

View File

@ -15,14 +15,25 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local fluidGenerator={}
fluidGenerator.getFormspec=function(pos,config)
-- Common functions
local function onConstruct(pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("charged",1)
inv:set_size("src",1)
inv:set_size("dst",1)
meta:set_float("fluidAmount",0)
meta:set_string("fluid","")
end
local function getFormspec(self,pos)
local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local fluidPercent=meta:get_float("fluidAmount")/100
local powerPercent=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")
local fluid=meta:get_string("fluid")
local fuel=config.getFuel(fluid)
local fuel=self.getFuel(fluid)
local tile=(fuel and fuel.texture or "industrialtest_gui_fluid_bg.png")
local formspec={
"list[context;src;2,1.8;1,1]",
@ -32,37 +43,47 @@ fluidGenerator.getFormspec=function(pos,config)
industrialtest.internal.getItemSlotBg(2,4.2,1,1),
"list[context;charged;6,3;1,1]",
industrialtest.internal.getItemSlotBg(6,3,1,1),
"box[9,1;0.3,4.8;#202020]",
(powerPercent>0 and "box[9,"..(1+4.8-(powerPercent*4.8))..";0.3,"..(powerPercent*4.8)..";#FF1010]" or ""),
self.createPowerIndicatorWidget(powerPercent,9,1),
"listring[context;src]",
"listring[context;dst]"
}
return table.concat(formspec,"")
return parentFormspec..table.concat(formspec,"")
end
fluidGenerator.onConstruct=function(pos,meta,inv)
inv:set_size("charged",1)
inv:set_size("src",1)
inv:set_size("dst",1)
meta:set_float("fluidAmount",0)
meta:set_string("fluid","")
local function allowMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex,count)
if toList=="dst" then
return 0
end
return count
end
fluidGenerator.onTimer=function(pos,elapsed,meta,inv,config)
local function allowMetadataInventoryPut(pos,listname,index,stack,player)
if listname=="dst" then
return 0
end
return stack:get_count()
end
local function takeFuelFromItem(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local fluidSlot=inv:get_stack("src",1)
local chargedSlot=inv:get_stack("charged",1)
local afterFlow,flowTransferred=industrialtest.api.powerFlow(pos)
local shouldUpdateFormspec=false
local shouldRerunTimer=(afterFlow and meta:get_int("industrialtest.powerAmount")>0)
if fluidSlot:get_count()>0 and meta:get_float("fluidAmount")<=9000 then
local fuel=config.getFuelByItem(fluidSlot:get_name())
if fuel and (fuel.name==meta:get_string("fluid") or meta:get_string("fluid")=="") then
local fluid=meta:get_string("fluid")
local fluidAmount=meta:get_float("fluidAmount")
if fluidSlot:is_empty() or fluidAmount>9000 then
return false
end
local fuel=self.getFuelByItem(fluidSlot:get_name())
if fuel and (fuel.name==fluid or fluid=="") then
local leftover=false
local leftoverAddingSucceeded=false
for _,item in ipairs(fuel.storageItems) do
if item.name==fluidSlot:get_name() and item.leftover then
if inv:room_for_item("dst",ItemStack(item.leftover)) then
inv:add_item("dst",ItemStack(item.leftover))
local leftoverItemstack=ItemStack(item.leftover)
if inv:room_for_item("dst",leftoverItemstack) then
inv:add_item("dst",leftoverItemstack)
leftoverAddingSucceeded=true
end
leftover=true
@ -72,193 +93,245 @@ fluidGenerator.onTimer=function(pos,elapsed,meta,inv,config)
fluidSlot:take_item()
inv:set_stack("src",1,fluidSlot)
meta:set_string("fluid",fuel.name)
meta:set_float("fluidAmount",meta:get_float("fluidAmount")+1000)
shouldUpdateFormspec=true
shouldRerunTimer=false
meta:set_float("fluidAmount",fluidAmount+1000)
return true
end
end
return false
end
if meta:get_float("fluidAmount")>=50 and not industrialtest.api.isFullyCharged(meta) then
meta:set_float("fluidAmount",meta:get_int("fluidAmount")-50*elapsed)
local toAdd=math.ceil(config.getFuel(meta:get_string("fluid")).calorificValue*elapsed)
local function generate(self,pos,elapsed)
local meta=minetest.get_meta(pos)
local fluidAmount=meta:get_float("fluidAmount")
if fluidAmount>0 and not industrialtest.api.isFullyCharged(meta) then
local fluidUsed=math.min(fluidAmount,50)
meta:set_float("fluidAmount",fluidAmount-fluidUsed*elapsed)
local toAdd=math.ceil(self.getFuel(meta:get_string("fluid")).calorificValue*elapsed*fluidUsed/50)
industrialtest.api.addPower(meta,toAdd)
shouldUpdateFormspec=true
if config.registerActiveVariant then
minetest.swap_node(pos,{
name="industrialtest:"..config.name.."_active",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
else
shouldRerunTimer=true
end
end
if chargedSlot:get_count()>0 and meta:get_int("industrialtest.powerAmount")>0 then
if industrialtest.api.transferPowerToItem(meta,chargedSlot,industrialtest.api.lvPowerFlow)>0 then
inv:set_stack("charged",1,chargedSlot)
shouldUpdateFormspec=true
shouldRerunTimer=true
end
end
if flowTransferred then
shouldUpdateFormspec=true
end
return shouldRerunTimer,shouldUpdateFormspec
return true
end
fluidGenerator.metadataChange=function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false
end
fluidGenerator.activeOnTimer=function(pos,elapsed,meta,inv,config)
local fluidSlot=inv:get_stack("src",1)
local chargedSlot=inv:get_stack("charged",1)
local afterFlow,flowTransferred=industrialtest.api.powerFlow(pos)
local shouldUpdateFormspec=false
local shouldRerunTimer=(afterFlow and meta:get_int("industrialtest.powerAmount")>0)
if fluidSlot:get_count()>0 and meta:get_float("fluidAmount")<=9000 then
local fuel=config.getFuelByItem(fluidSlot:get_name())
if fuel and (fuel.name==meta:get_string("fluid") or meta:get_string("fluid")=="") then
local leftover=false
local leftoverAddingSucceeded=false
for _,item in ipairs(fuel.storageItems) do
if item.name==fluidSlot:get_name() and item.leftover then
if inv:room_for_item("dst",ItemStack(item.leftover)) then
inv:add_item("dst",ItemStack(item.leftover))
leftoverAddingSucceeded=true
end
leftover=true
end
end
if not leftover or leftoverAddingSucceeded then
fluidSlot:take_item()
inv:set_stack("src",1,fluidSlot)
meta:set_string("fluid",fuel.name)
meta:set_float("fluidAmount",meta:get_float("fluidAmount")+1000)
shouldUpdateFormspec=true
shouldRerunTimer=false
end
end
end
if meta:get_float("fluidAmount")>=50 and not industrialtest.api.isFullyCharged(meta) then
meta:set_float("fluidAmount",meta:get_int("fluidAmount")-50*elapsed)
local toAdd=math.ceil(industrialtest.api.getGeothermalGeneratorFuel(meta:get_string("fluid")).calorificValue*elapsed)
industrialtest.api.addPower(meta,toAdd)
shouldUpdateFormspec=true
shouldRerunTimer=true
else
minetest.swap_node(pos,{
name="industrialtest:"..config.name,
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
if chargedSlot:get_count()>0 and meta:get_int("industrialtest.powerAmount")>0 then
if industrialtest.api.transferPowerToItem(meta,chargedSlot,industrialtest.api.lvPowerFlow)>0 then
inv:set_stack("charged",1,chargedSlot)
shouldUpdateFormspec=true
shouldRerunTimer=true
end
end
if flowTransferred then
shouldUpdateFormspec=true
end
return shouldRerunTimer,shouldUpdateFormspec
end
local function registerFluidGenerator(config)
local definition={
name=config.name,
displayName=config.displayName,
getFormspec=function(pos)
return fluidGenerator.getFormspec(pos,config)
end,
industrialtest.GeothermalGenerator=table.copy(industrialtest.ActivatedElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.GeothermalGenerator,{
name="industrialtest:geothermal_generator",
description=S("Geothermal Generator"),
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_geothermal_generator_front.png"
},
sounds="metal",
facedir=true,
storageLists={
"src",
"dst",
"charged"
},
active={
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_geothermal_generator_front_active.png"
},
lightSource=10
},
powerLists={
{
list="charged",
direction="o"
}
},
requiresWrench=true,
hasPowerOutput=true,
capacity=7000,
flow=industrialtest.api.lvPowerFlow,
ioConfig="oooooo",
requiresWrench=true,
registerActiveVariant=config.registerActiveVariant,
powerSlots={"charged"},
storageSlots={"src","dst"},
sounds="metal",
groups={
_industrialtest_hasPowerOutput=1
},
customKeys={
tiles={
"industrialtest_machine_block.png"..(config.customTopTexture and "^"..config.customTopTexture or ""),
"industrialtest_machine_block.png"..(config.customBottomTexture and "^"..config.customBottomTexture or ""),
"industrialtest_machine_block.png"..(config.customRightTexture and "^"..config.customRightTexture or ""),
"industrialtest_machine_block.png"..(config.customLeftTexture and "^"..config.customLeftTexture or ""),
"industrialtest_machine_block.png"..(config.customBackTexture and "^"..config.customBackTexture or ""),
"industrialtest_machine_block.png"..(config.customFrontTexture and "^"..config.customFrontTexture or "")
},
paramtype2="facedir",
legacy_facedir_simple=true
},
onConstruct=fluidGenerator.onConstruct,
onTimer=function(pos,elapsed,meta,inv)
return fluidGenerator.onTimer(pos,elapsed,meta,inv,config)
end,
onMetadataInventoryPut=fluidGenerator.metadataChange,
onMetadataInventoryMove=fluidGenerator.metadataChange
}
if config.registerActiveVariant then
definition.activeCustomKeys={
tiles={
"industrialtest_machine_block.png"..(config.customTopTexture and "^"..config.customTopTextureActive or ""),
"industrialtest_machine_block.png"..(config.customBottomTexture and "^"..config.customBottomTextureActive or ""),
"industrialtest_machine_block.png"..(config.customRightTexture and "^"..config.customRightTextureActive or ""),
"industrialtest_machine_block.png"..(config.customLeftTexture and "^"..config.customLeftTextureActive or ""),
"industrialtest_machine_block.png"..(config.customBackTexture and "^"..config.customBackTextureActive or ""),
"industrialtest_machine_block.png"..(config.customFrontTexture and "^"..config.customFrontTextureActive or "")
},
light_source=8
}
definition.activeOnTimer=function(pos,elapsed,meta,inv)
return fluidGenerator.activeOnTimer(pos,elapsed,meta,inv,config)
end
end
industrialtest.internal.registerMachine(definition)
end
registerFluidGenerator({
name="geothermal_generator",
displayName=S("Geothermal Generator"),
customFrontTexture="industrialtest_geothermal_generator_front.png",
customFrontTextureActive="industrialtest_geothermal_generator_front_active.png",
getFormspec=getFormspec,
getFuel=industrialtest.api.getGeothermalGeneratorFuel,
getFuelByItem=industrialtest.api.getGeothermalGeneratorFuelByItem,
registerActiveVariant=true,
reactsToNeighbouringNodes=false
getFuelByItem=industrialtest.api.getGeothermalGeneratorFuelByItem
})
registerFluidGenerator({
name="water_mill",
displayName=S("Water Mill"),
customLeftTexture="industrialtest_water_mill_side.png",
customRightTexture="industrialtest_water_mill_side.png",
customFrontTexture="industrialtest_water_mill_side.png",
customBackTexture="industrialtest_water_mill_side.png",
getFuel=industrialtest.api.getWaterMillFuel,
getFuelByItem=industrialtest.api.getWaterMillFuelByItem,
registerActiveVariant=false
})
local neighbors={}
for key,_ in pairs(industrialtest.api.waterMillFuels) do
table.insert(neighbors,key)
function industrialtest.GeothermalGenerator.onConstruct(self,pos)
onConstruct(pos)
industrialtest.ActivatedElectricMachine.onConstruct(self,pos)
end
minetest.register_abm({
label="Water Mill generating",
nodenames={"industrialtest:water_mill"},
neighbors=neighbors,
interval=industrialtest.updateDelay,
chance=1,
action=function(pos,node)
function industrialtest.GeothermalGenerator.update(self,pos,elapsed,meta,inv)
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
local shouldUpdateFormspec=takeFuelFromItem(self,pos)
return (not srcSlot:is_empty() and dstSlot:get_free_space()>0 and not industrialtest.api.isFluidStorageFull(meta)),shouldUpdateFormspec
end
function industrialtest.GeothermalGenerator.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
return math.min(allowMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex,count),industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count))
end
function industrialtest.GeothermalGenerator.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
return math.min(allowMetadataInventoryPut(pos,listname,index,stack,player),industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player))
end
function industrialtest.GeothermalGenerator.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
if toList=="src" and takeFuelFromItem(self,pos) then
self:trigger(pos)
end
industrialtest.ActivatedElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
function industrialtest.GeothermalGenerator.onMetadataInventoryPut(self,pos,listname,index,stack)
if listname=="src" and takeFuelFromItem(self,pos) then
self:trigger(pos)
end
industrialtest.ActivatedElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack)
end
function industrialtest.GeothermalGenerator.shouldActivate(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local chargedSlot=inv:get_stack("charged",1)
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
local fluidAmount=meta:get_float("fluidAmount")
return (fluidAmount>0 or (not srcSlot:is_empty() and dstSlot:get_free_space()>0)) and not industrialtest.api.isFullyCharged(meta)
end
function industrialtest.GeothermalGenerator.shouldDeactivate(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
local fluidAmount=meta:get_float("fluidAmount")
return (fluidAmount<=0 and (srcSlot:is_empty() or dstSlot:get_free_space()==0)) or industrialtest.api.isFullyCharged(meta)
end
function industrialtest.GeothermalGenerator.activeUpdate(self,pos,elapsed)
local shouldUpdateFormspec=false
if takeFuelFromItem(self,pos) then
shouldUpdateFormspec=true
end
if generate(self,pos,elapsed) then
shouldUpdateFormspec=true
end
return shouldUpdateFormspec
end
industrialtest.GeothermalGenerator:register()
minetest.register_craft({
type="shaped",
output="industrialtest:geothermal_generator",
recipe={
{industrialtest.elementKeys.glass,"industrialtest:empty_cell",industrialtest.elementKeys.glass},
{industrialtest.elementKeys.glass,"industrialtest:empty_cell",industrialtest.elementKeys.glass},
{"industrialtest:refined_iron_ingot","industrialtest:generator","industrialtest:refined_iron_ingot"}
}
})
industrialtest.WaterMill=table.copy(industrialtest.ElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.WaterMill,{
name="industrialtest:water_mill",
description=S("Water Mill"),
tiles={
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png^industrialtest_water_mill_side.png",
"industrialtest_machine_block.png^industrialtest_water_mill_side.png",
"industrialtest_machine_block.png^industrialtest_water_mill_side.png",
"industrialtest_machine_block.png^industrialtest_water_mill_side.png"
},
sounds="metal",
storageLists={
"src",
"dst",
"charged"
},
powerLists={
{
list="charged",
direction="o"
}
},
requiresWrench=true,
hasPowerOutput=true,
capacity=7000,
flow=industrialtest.api.lvPowerFlow,
ioConfig="oooooo",
getFormspec=getFormspec,
getFuel=industrialtest.api.getWaterMillFuel,
getFuelByItem=industrialtest.api.getWaterMillFuelByItem
})
function industrialtest.WaterMill.onConstruct(self,pos)
onConstruct(pos)
industrialtest.ElectricMachine.onConstruct(self,pos)
end
function industrialtest.WaterMill.canUpdate(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
local fluidAmount=meta:get_float("fluidAmount")
return (fluidAmount>0 or (not srcSlot:is_empty() and dstSlot:get_free_space()>0)) and not industrialtest.api.isFullyCharged(meta)
end
function industrialtest.WaterMill.update(self,pos,elapsed)
local shouldUpdateFormspec=false
local shouldRerunTimer=false
if takeFuelFromItem(self,pos) then
shouldUpdateFormspec=true
shouldRerunTimer=true
end
if generate(self,pos,elapsed) then
shouldUpdateFormspec=true
shouldRerunTimer=true
end
return shouldRerunTimer,shouldUpdateFormspec
end
function industrialtest.WaterMill.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
return math.min(allowMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex,count),industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count))
end
function industrialtest.WaterMill.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
return math.min(allowMetadataInventoryPut(pos,listname,index,stack,player),industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player))
end
function industrialtest.WaterMill.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
if toList=="src" and takeFuelFromItem(self,pos) then
self:trigger(pos)
end
industrialtest.ElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
function industrialtest.WaterMill.onMetadataInventoryPut(self,pos,listname,index,stack)
if listname=="src" and takeFuelFromItem(self,pos) then
self:trigger(pos)
end
industrialtest.ElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack)
end
function industrialtest.WaterMill.action(self,pos)
local meta=minetest.get_meta(pos)
local powerToAdd=0
local neighbourPositions={
vector.offset(pos,-1,0,0),
@ -278,14 +351,25 @@ minetest.register_abm({
end
end
if industrialtest.api.addPower(meta,powerToAdd)>0 then
local def=minetest.registered_nodes[node.name]
def._industrialtest_updateFormspec(meta)
end
if chargedSlot:get_count()>0 and meta:get_int("industrialtest.powerAmount")>0 then
if industrialtest.api.transferPowerToItem(meta,chargedSlot,industrialtest.api.lvPowerFlow)>0 then
inv:set_stack("charged",1,chargedSlot)
self:updateFormspec(pos)
self:trigger(pos)
end
end
industrialtest.WaterMill:register()
local neighbors={}
for key,_ in pairs(industrialtest.api.waterMillFuels) do
table.insert(neighbors,key)
end
minetest.register_abm({
label="Water Mill generating",
nodenames={"industrialtest:water_mill"},
neighbors=neighbors,
interval=industrialtest.config.updateDelay,
chance=1,
action=function(pos)
industrialtest.WaterMill:action(pos)
end
})

View File

@ -15,11 +15,61 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local generator={}
industrialtest.Generator=table.copy(industrialtest.ActivatedElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.Generator,{
name="industrialtest:generator",
description=S("Generator"),
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_iron_furnace_front.png"
},
sounds="metal",
facedir=true,
storageLists={
"src",
"charged"
},
active={
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_iron_furnace_front_active.png"
},
lightSource=8
},
capacity=7000,
flow=industrialtest.api.lvPowerFlow,
ioConfig="oooooo",
hasPowerOutput=true,
powerLists={
{
list="charged",
direction="o"
}
}
})
generator.getFormspec=function(pos)
function industrialtest.Generator.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local fuelPercent=meta:get_int("fuelTime")/meta:get_int("maxFuelTime")*100
local inv=meta:get_inventory()
inv:set_size("charged",1)
inv:set_size("src",1)
meta:set_float("fuelTime",0)
meta:set_float("maxFuelTime",1)
industrialtest.ActivatedElectricMachine.onConstruct(self,pos)
end
function industrialtest.Generator.getFormspec(self,pos)
local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local fuelPercent=meta:get_float("fuelTime")/meta:get_float("maxFuelTime")*100
local charged=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")
local formspec={
"list[context;charged;4.7,1.8;1,1]",
@ -28,140 +78,87 @@ generator.getFormspec=function(pos)
or "image[4.7,2.8;1,1;default_furnace_fire_bg.png]"),
"list[context;src;4.7,3.9;1,1]",
industrialtest.internal.getItemSlotBg(4.7,3.9,1,1),
"box[9,1;0.3,4.8;#202020]",
(charged>0 and "box[9,"..(1+4.8-(charged*4.8))..";0.3,"..(charged*4.8)..";#FF1010]" or ""),
self.createPowerIndicatorWidget(charged,9,1),
"listring[context;src]"
}
return table.concat(formspec,"")
return parentFormspec..table.concat(formspec,"")
end
generator.onConstruct=function(pos,meta,inv)
inv:set_size("charged",1)
inv:set_size("src",1)
meta:set_int("fuelTime",0)
meta:set_int("maxFuelTime",1)
function industrialtest.Generator.onMetadataInventoryPut(self,pos,listname,index,stack)
self:triggerIfNeeded(pos)
industrialtest.ActivatedElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack)
end
generator.onTimer=function(pos,elapsed,meta,inv)
local powerFlow=meta:get_int("industrialtest.powerFlow")
function industrialtest.Generator.activeUpdate(self,pos,elapsed,meta,inv)
local chargedSlot=inv:get_stack("charged",1)
local fuelSlot=inv:get_stack("src",1)
local afterFlow,flowTransferred=industrialtest.api.powerFlow(pos)
local shouldUpdateFormspec=flowTransferred
local shouldRerunTimer=(afterFlow and meta:get_int("industrialtest.powerAmount")>0)
if chargedSlot:get_count()>0 and not industrialtest.api.isFullyCharged(chargedSlot:get_meta()) and meta:get_int("industrialtest.powerAmount")>0 then
industrialtest.api.transferPowerToItem(meta,chargedSlot,powerFlow)
inv:set_stack("charged",1,chargedSlot)
shouldUpdateFormspec=true
shouldRerunTimer=true
end
if fuelSlot:get_count()>0 and meta:get_int("fuelTime")<=0 and not industrialtest.api.isFullyCharged(meta) then
local shouldUpdateFormspec=false
if fuelSlot:get_count()>0 and meta:get_float("fuelTime")<=0 and not industrialtest.api.isFullyCharged(meta) then
local output,after=minetest.get_craft_result({
method="fuel",
width=1,
items={fuelSlot}
})
if output.time>0 then
meta:set_int("fuelTime",output.time)
meta:set_int("maxFuelTime",output.time)
meta:set_float("fuelTime",output.time)
meta:set_float("maxFuelTime",output.time)
inv:set_stack("src",1,after.items[1])
minetest.swap_node(pos,{
name="industrialtest:generator_active",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
end
return shouldRerunTimer,shouldUpdateFormspec
end
generator.activeOnTimer=function(pos,elapsed,meta,inv)
local chargedSlot=inv:get_stack("charged",1)
local fuelSlot=inv:get_stack("src",1)
local afterFlow,flowTransferred=industrialtest.api.powerFlow(pos)
local shouldUpdateFormspec=flowTransferred
local shouldRerunTimer=(afterFlow and meta:get_int("industrialtest.powerAmount")>0)
if chargedSlot:get_count()>0 and not industrialtest.api.isFullyCharged(chargedSlot:get_meta()) and meta:get_int("industrialtest.powerAmount")>0 then
industrialtest.api.transferPowerToItem(meta,chargedSlot,chargedSlot:get_meta():get_int("industrialtest.powerFlow"))
inv:set_stack("charged",1,chargedSlot)
shouldUpdateFormspec=true
shouldRerunTimer=true
end
if fuelSlot:get_count()>0 and meta:get_int("fuelTime")<=0 and not industrialtest.api.isFullyCharged(meta) then
local output,after=minetest.get_craft_result({
method="fuel",
width=1,
items={fuelSlot}
})
if output.time>0 then
meta:set_int("fuelTime",output.time)
meta:set_int("maxFuelTime",output.time)
inv:set_stack("src",1,after.items[1])
end
end
if meta:get_int("fuelTime")>0 then
meta:set_int("fuelTime",meta:get_int("fuelTime")-elapsed)
if meta:get_float("fuelTime")>0 then
meta:set_float("fuelTime",meta:get_float("fuelTime")-elapsed)
industrialtest.api.addPower(meta,200)
shouldUpdateFormspec=true
shouldRerunTimer=true
else
minetest.swap_node(pos,{
name="industrialtest:generator",
param2=minetest.get_node(pos).param2
})
end
return shouldRerunTimer,shouldUpdateFormspec
end
generator.metadataChange=function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return shouldUpdateFormspec
end
industrialtest.internal.registerMachine({
name="generator",
displayName=S("Generator"),
getFormspec=generator.getFormspec,
capacity=7000,
flow=industrialtest.api.lvPowerFlow,
ioConfig="oooooo",
registerActiveVariant=true,
powerSlots={"charged"},
storageSlots={"charged","src"},
sounds="metal",
groups={
_industrialtest_hasPowerOutput=1
},
customKeys={
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_iron_furnace_front.png",
"industrialtest_machine_block.png"
},
paramtype2="facedir",
legacy_facedir_simple=true
},
activeCustomKeys={
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_iron_furnace_front_active.png",
"industrialtest_machine_block.png"
},
light_source=8
},
onConstruct=generator.onConstruct,
onTimer=generator.onTimer,
activeOnTimer=generator.activeOnTimer,
onMetadataInventoryPut=generator.metadataChange,
onMetadataInventoryMove=generator.metadataChange
function industrialtest.Generator.shouldActivate(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local fuelSlot=inv:get_stack("src",1)
if fuelSlot:get_count()>0 and not industrialtest.api.isFullyCharged(meta) then
local output,after=minetest.get_craft_result({
method="fuel",
width=1,
items={fuelSlot}
})
if output.time>0 then
return true
end
end
return false
end
function industrialtest.Generator.shouldDeactivate(self,pos)
local meta=minetest.get_meta(pos)
if meta:get_float("fuelTime")>0 then
return false
end
local inv=meta:get_inventory()
local fuelSlot=inv:get_stack("src",1)
if fuelSlot:get_count()>0 and not industrialtest.api.isFullyCharged(meta) then
local output,after=minetest.get_craft_result({
method="fuel",
width=1,
items={fuelSlot}
})
if output.time>0 then
return false
end
end
return true
end
industrialtest.Generator:register()
minetest.register_craft({
type="shaped",

View File

@ -15,29 +15,65 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.InductionFurnace=table.copy(industrialtest.ActivatedElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.InductionFurnace,{
name="industrialtest:induction_furnace",
description=S("Induction Furnace"),
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_electric_furnace_front.png"
},
sounds="metal",
requiresWrench=true,
facedir=true,
storageLists={
"src",
"dst",
"upgrades",
"powerStorage"
},
powerLists={
{
list="powerStorage",
direction="i"
}
},
active={
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_electric_furnace_front_active.png"
}
},
capacity=industrialtest.api.mvPowerFlow*2,
flow=industrialtest.api.mvPowerFlow,
hasPowerInput=true,
ioConfig="iiiiii",
_opPower=60,
_efficiency=0.5
})
local inductionFurnace={}
inductionFurnace.opPower=60
inductionFurnace.efficiency=0.5
local function calculateMaxSrcTime(pos)
function industrialtest.InductionFurnace.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcList=inv:get_list("src")
local maxSrcTime=0
for _,slot in ipairs(srcList) do
local result,_=minetest.get_craft_result({
method="cooking",
width=1,
items={slot}
})
maxSrcTime=math.max(maxSrcTime,result.time*inductionFurnace.efficiency)
end
meta:set_float("maxSrcTime",maxSrcTime)
inv:set_size("src",2)
inv:set_size("dst",2)
inv:set_size("powerStorage",1)
inv:set_size("upgrades",4)
meta:set_int("heat",0)
meta:set_float("srcTime",0)
industrialtest.ActivatedElectricMachine.onConstruct(self,pos)
end
inductionFurnace.getFormspec=function(pos)
function industrialtest.InductionFurnace.getFormspec(self,pos)
local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local powerPercent=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")*100
local maxSrcTime=meta:get_float("maxSrcTime")
@ -60,32 +96,74 @@ inductionFurnace.getFormspec=function(pos)
"listring[context;src]",
"listring[context;dst]"
}
return table.concat(formspec,"")
return parentFormspec..table.concat(formspec,"")
end
inductionFurnace.onConstruct=function(pos,meta,inv)
inv:set_size("src",2)
inv:set_size("dst",2)
inv:set_size("powerStorage",1)
inv:set_size("upgrades",4)
meta:set_int("heat",0)
meta:set_float("srcTime",0)
end
inductionFurnace.onTimer=function(pos,elapsed,meta,inv)
local shouldRerunTimer=false
local shouldUpdateFormspec=false
function industrialtest.InductionFurnace.update(self,pos,elapsed,meta,inv)
local srcList=inv:get_list("src")
local heat=meta:get_int("heat")
shouldRerunTimer,shouldUpdateFormspec=industrialtest.internal.chargeFromPowerStorageItem(meta,inv)
local shouldRerunTimer=false
local shouldUpdateFormspec=false
if heat>0 then
meta:set_int("heat",math.max(heat-math.max(2*elapsed,1),0))
shouldRerunTimer=shouldRerunTimer or heat>0
shouldRerunTimer=true
shouldUpdateFormspec=true
end
return shouldRerunTimer,shouldUpdateFormspec
end
function industrialtest.InductionFurnace.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
if toList=="dst" then
return 0
end
return industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
function industrialtest.InductionFurnace.allowMetadataInventoryPut(self,pos,listname,index,stack)
if listname=="dst" then
return 0
end
return industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack)
end
function industrialtest.InductionFurnace.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
industrialtest.ActivatedElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
if fromList=="src" or toList=="src" then
self:calculateMaxSrcTime(pos)
end
if fromList=="src" and self.isInputEmpty(pos) then
local meta=minetest.get_meta(pos)
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
self:updateFormspec(pos)
elseif toList=="src" or (fromList=="dst" and not self.isOutputFull(pos)) then
self:triggerIfNeeded(pos)
end
end
function industrialtest.InductionFurnace.onMetadataInventoryPut(self,pos,listname,index,stack,player)
industrialtest.ActivatedElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack,player)
if listname=="src" then
self:calculateMaxSrcTime(pos)
self:triggerIfNeeded(pos)
end
end
function industrialtest.InductionFurnace.onMetadataInventoryTake(self,pos,listname,index,stack)
if listname=="src" then
self:calculateMaxSrcTime(pos)
elseif listname=="dst" and not self.isOutputFull(pos) then
self:triggerIfNeeded(pos)
end
end
function industrialtest.InductionFurnace.shouldActivate(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcList=inv:get_list("src")
for _,slot in ipairs(srcList) do
if not slot:is_empty() then
local result,after=minetest.get_craft_result({
@ -94,68 +172,27 @@ inductionFurnace.onTimer=function(pos,elapsed,meta,inv)
items={slot}
})
if result.time>0 and inv:room_for_item("dst",result.item) then
minetest.swap_node(pos,{
name="industrialtest:induction_furnace_active",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false,shouldUpdateFormspec
return meta:get_int("industrialtest.powerAmount")>=self._opPower
end
end
end
return shouldRerunTimer,shouldUpdateFormspec
return false
end
inductionFurnace.allowMetadataInventoryMove=function(pos,fromList,fromIndex,toList,toIndex,count)
if toList=="dst" then
return 0
end
return count
function industrialtest.InductionFurnace.shouldDeactivate(self,pos)
return not self:shouldActivate(pos)
end
inductionFurnace.allowMetadataInventoryPut=function(pos,listname,index,stack)
if listname=="dst" then
return 0
end
return stack:get_count()
end
inductionFurnace.onMetadataInventoryPut=function(pos,listname)
if listname=="src" then
calculateMaxSrcTime(pos)
end
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
inductionFurnace.onMetadataInventoryMove=function(pos,fromList,fromIndex,toList)
if fromList=="src" or toList=="src" then
calculateMaxSrcTime(pos)
end
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
inductionFurnace.onMetadataInventoryTake=function(pos,listname)
if listname=="src" then
calculateMaxSrcTime(pos)
end
if listname=="dst" then
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
end
inductionFurnace.activeOnTimer=function(pos,elapsed,meta,inv)
function industrialtest.InductionFurnace.activeUpdate(self,pos,elapsed,meta,inv)
local srcList=inv:get_list("src")
local powerAmount=meta:get_int("industrialtest.powerAmount")
local srcTime=meta:get_float("srcTime")
local maxSrcTime=meta:get_float("maxSrcTime")
local heat=meta:get_int("heat")
local speed=industrialtest.api.getMachineSpeed(meta)
local requiredPower=elapsed*inductionFurnace.opPower*speed
local requiredPower=elapsed*self._opPower*speed
industrialtest.internal.chargeFromPowerStorageItem(meta,inv)
local shouldContinue=false
local results={}
for _,slot in ipairs(srcList) do
if slot:is_empty() then
@ -168,23 +205,13 @@ inductionFurnace.activeOnTimer=function(pos,elapsed,meta,inv)
})
if result.time>0 and inv:room_for_item("dst",result.item) then
table.insert(results,result.item)
shouldContinue=true
else
table.insert(results,false)
end
end
end
if not shouldContinue or powerAmount<requiredPower then
meta:set_float("srcTime",0)
minetest.swap_node(pos,{
name="industrialtest:induction_furnace",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false,true
end
srcTime=srcTime+elapsed*(1+heat/100)
srcTime=srcTime+elapsed*(1+heat/200)
if srcTime>=maxSrcTime then
for i,result in ipairs(results) do
if result then
@ -206,55 +233,56 @@ inductionFurnace.activeOnTimer=function(pos,elapsed,meta,inv)
industrialtest.api.addPower(meta,-requiredPower)
return true,true
return true
end
industrialtest.internal.registerMachine({
name="induction_furnace",
displayName=S("Induction Furnace"),
capacity=industrialtest.api.mvPowerFlow*2,
getFormspec=inductionFurnace.getFormspec,
flow=industrialtest.api.mvPowerFlow,
ioConfig="iiiiii",
requiresWrench=true,
registerActiveVariant=true,
sounds="metal",
powerSlots={"powerStorage"},
storageSlots={"src","dst","powerStorage","upgrades"},
groups={
_industrialtest_hasPowerInput=1
},
customKeys={
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_electric_furnace_front.png"
},
paramtype2="facedir",
legacy_facedir_simple=true
},
activeCustomKeys={
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_electric_furnace_front_active.png"
}
},
onConstruct=inductionFurnace.onConstruct,
onTimer=inductionFurnace.onTimer,
allowMetadataInventoryMove=inductionFurnace.allowMetadataInventoryMove,
allowMetadataInventoryPut=inductionFurnace.allowMetadataInventoryPut,
onMetadataInventoryPut=inductionFurnace.onMetadataInventoryPut,
onMetadataInventoryMove=inductionFurnace.onMetadataInventoryMove,
onMetadataInventoryTake=inductionFurnace.onMetadataInventoryTake,
activeOnTimer=inductionFurnace.activeOnTimer
function industrialtest.InductionFurnace.calculateMaxSrcTime(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcList=inv:get_list("src")
local maxSrcTime=0
for _,slot in ipairs(srcList) do
local result,_=minetest.get_craft_result({
method="cooking",
width=1,
items={slot}
})
maxSrcTime=math.max(maxSrcTime,result.time*self._efficiency)
end
meta:set_float("maxSrcTime",maxSrcTime)
end
function industrialtest.InductionFurnace.isInputEmpty(pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcList=inv:get_list("src")
for _,slot in ipairs(srcList) do
if not slot:is_empty() then
return false
end
end
return true
end
function industrialtest.InductionFurnace.isOutputFull(pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local dstList=inv:get_list("dst")
for _,slot in ipairs(dstList) do
if slot:get_free_space()>0 then
return false
end
end
return true
end
industrialtest.InductionFurnace:register()
minetest.register_craft({
type="shaped",
output="industrialtest:induction_furnace",

View File

@ -15,15 +15,59 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local ironFurnace={}
industrialtest.IronFurnace=table.copy(industrialtest.ActivatedMachine)
industrialtest.internal.unpackTableInto(industrialtest.IronFurnace,{
name="industrialtest:iron_furnace",
description=S("Iron Furnace"),
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_iron_furnace_front.png"
},
active={
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_iron_furnace_front_active.png"
},
lightSource=8
},
facedir=true,
storageLists={
"src",
"fuel",
"dst"
}
})
ironFurnace.getFormspec=function(fuelPercent,srcPercent)
function industrialtest.IronFurnace.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("src",1)
inv:set_size("dst",1)
inv:set_size("fuel",1)
meta:set_float("fuelTime",0)
meta:set_float("maxFuelTime",1)
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",0)
industrialtest.ActivatedMachine.onConstruct(self,pos)
end
function industrialtest.IronFurnace.getFormspec(self,pos)
local parentFormspec=industrialtest.ActivatedMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local fuelPercent=meta:get_float("fuelTime")/meta:get_float("maxFuelTime")*100
local maxSrcTime=meta:get_float("maxSrcTime")
local srcPercent=meta:get_float("srcTime")/(maxSrcTime>0 and maxSrcTime or 0)*100
local formspec
if industrialtest.mtgAvailable then
formspec={
"formspec_version[4]",
"size[10.8,12]",
"label[0.5,0.5;"..S("Iron Furnace").."]",
"list[context;src;3.4,1.8;1,1]",
(fuelPercent>0 and "image[3.4,2.8;1,1;default_furnace_fire_bg.png^[lowpart:"..fuelPercent..":default_furnace_fire_fg.png]"
or "image[3.4,2.8;1,1;default_furnace_fire_bg.png]"),
@ -31,16 +75,11 @@ ironFurnace.getFormspec=function(fuelPercent,srcPercent)
(srcPercent>0 and "image[4.9,2.8;1,1;gui_furnace_arrow_bg.png^[lowpart:"..srcPercent..":gui_furnace_arrow_fg.png^[transformR270]"
or "image[4.9,2.8;1,1;gui_furnace_arrow_bg.png^[transformR270]"),
"list[context;dst;6.4,2.8;1,1]",
"list[current_player;main;0.5,6.25;8,1]",
"list[current_player;main;0.5,7.5;8,3;8]",
"listring[current_player;main]",
"listring[context;src]",
"listring[context;dst]"
}
elseif industrialtest.mclAvailable then
formspec={
"size[10.04,12]",
"label[0.25,0.25;"..S("Iron Furnace").."]",
"list[context;src;3.4,1.8;1,1]",
mcl_formspec.get_itemslot_bg(3.4,1.8,1,1),
(fuelPercent>0 and "image[3.4,2.8;1,1;default_furnace_fire_bg.png^[lowpart:"..fuelPercent..":default_furnace_fire_fg.png]"
@ -51,79 +90,78 @@ ironFurnace.getFormspec=function(fuelPercent,srcPercent)
or "image[4.9,2.8;1,1;gui_furnace_arrow_bg.png^[transformR270]"),
"list[context;dst;6.4,2.8;1,1]",
mcl_formspec.get_itemslot_bg(6.4,2.8,1,1),
"list[current_player;main;0.5,7;9,3;9]",
mcl_formspec.get_itemslot_bg(0.5,7,9,3),
"list[current_player;main;0.5,10.24;9,1]",
mcl_formspec.get_itemslot_bg(0.5,10.24,9,1),
"listring[current_player;main]",
"listring[context;src]",
"listring[context;dst]"
}
end
return table.concat(formspec,"")
return parentFormspec..table.concat(formspec,"")
end
ironFurnace.onConstruct=function(pos)
function industrialtest.IronFurnace.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
if toList=="dst" then
return 0
end
return industrialtest.ActivatedMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
function industrialtest.IronFurnace.allowMetadataInventoryPut(self,pos,listname,index,stack)
if listname=="dst" then
return 0
elseif listname=="src" then
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("src",1)
inv:set_size("dst",1)
inv:set_size("fuel",1)
meta:set_string("formspec",ironFurnace.getFormspec(0,0))
meta:set_float("fuelTime",0)
meta:set_float("maxFuelTime",1)
local srcSlot=inv:get_stack("src",1)
if srcSlot:get_name()~=stack:get_name() then
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",0)
end
end
return industrialtest.ActivatedMachine.allowMetadataInventoryPut(self,pos,listname,index,stack)
end
function industrialtest.IronFurnace.allowMetadataInventoryTake(self,pos,listname,index,stack)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
if listname=="src" and stack:get_count()==srcSlot:get_count() then
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",0)
if meta:get_float("maxFuelTime")>0 then
self:updateFormspec(pos)
end
elseif listname=="dst" and dstSlot:get_free_space()==0 then
self:triggerIfNeeded(pos)
end
return industrialtest.ActivatedMachine.allowMetadataInventoryTake(self,pos,listname,index,stack)
end
function industrialtest.IronFurnace.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
if fromList=="src" and count==srcSlot:get_count() then
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
if meta:get_float("maxFuelTime")>0 then
self:updateFormspec(pos)
end
elseif fromList=="dst" and dstSlot:get_free_space()==0 then
self:triggerIfNeeded(pos)
end
industrialtest.ActivatedMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
ironFurnace.onTimer=function(pos,elapsed)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
function industrialtest.IronFurnace.onMetadataInventoryPut(self,pos,listname,index,stack)
self:triggerIfNeeded(pos)
industrialtest.ActivatedMachine.onMetadataInventoryPut(self,pos,listname,index,stack)
end
function industrialtest.IronFurnace.activeUpdate(self,pos,elapsed,meta,inv)
local srcSlot=inv:get_stack("src",1)
local fuelSlot=inv:get_stack("fuel",1)
local shouldUpdateFormspec=false
local shouldRerunTimer=false
if fuelSlot:get_count()>0 and meta:get_float("fuelTime")<=0 then
local output,after=minetest.get_craft_result({
method="cooking",
width=1,
items={srcSlot}
})
if output.time>0 and inv:room_for_item("dst",output.item) then
output,after=minetest.get_craft_result({
method="fuel",
width=1,
items={fuelSlot}
})
if output.time>0 then
meta:set_float("fuelTime",output.time)
meta:set_float("maxFuelTime",output.time)
inv:set_stack("fuel",1,after.items[1])
minetest.swap_node(pos,{
name="industrialtest:iron_furnace_active",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
end
end
if shouldUpdateFormspec then
meta:set_string("formspec",ironFurnace.getFormspec(meta:get_float("fuelTime")/meta:get_float("maxFuelTime")*100,meta:get_float("srcTime")/meta:get_float("maxSrcTime")*100))
end
return shouldRerunTimer
end
ironFurnace.activeOnTimer=function(pos,elapsed)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local fuelSlot=inv:get_stack("fuel",1)
local shouldUpdateFormspec=false
local shouldRerunTimer=false
if fuelSlot:get_count()>0 and meta:get_float("fuelTime")<=0 then
local output,after=minetest.get_craft_result({
@ -155,30 +193,12 @@ ironFurnace.activeOnTimer=function(pos,elapsed)
meta:set_float("maxSrcTime",output.time*0.7)
end
end
if meta:get_float("fuelTime")>0 then
if meta:get_float("maxSrcTime")>0 then
if meta:get_float("fuelTime")>0 then
meta:set_float("srcTime",meta:get_float("srcTime")+elapsed)
else
meta:set_float("srcTime",0)
minetest.swap_node(pos,{
name="industrialtest:iron_furnace",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
shouldUpdateFormspec=true
shouldRerunTimer=true
elseif meta:get_float("fuelTime")<=0 then
minetest.swap_node(pos,{
name="industrialtest:iron_furnace",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
if meta:get_float("fuelTime")>0 then
meta:set_float("fuelTime",meta:get_float("fuelTime")-elapsed)
shouldUpdateFormspec=true
shouldRerunTimer=true
end
if meta:get_float("srcTime")>=meta:get_float("maxSrcTime") then
local output,after=minetest.get_craft_result({
@ -194,145 +214,77 @@ ironFurnace.activeOnTimer=function(pos,elapsed)
end
end
if shouldUpdateFormspec then
meta:set_string("formspec",ironFurnace.getFormspec(meta:get_float("fuelTime")/meta:get_float("maxFuelTime")*100,meta:get_float("srcTime")/meta:get_float("maxSrcTime")*100))
return shouldUpdateFormspec
end
return shouldRerunTimer
end
ironFurnace.allowMetadataInventoryMove=function(pos,fromList,fromIndex,toList,toIndex,count)
if toList=="dst" then
return 0
end
return count
end
ironFurnace.allowMetadataInventoryPut=function(pos,listname,index,stack)
if listname=="dst" then
return 0
elseif listname=="src" then
function industrialtest.IronFurnace.shouldActivate(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local fuelSlot=inv:get_stack("fuel",1)
if fuelSlot:get_count()>0 then
local srcSlot=inv:get_stack("src",1)
if srcSlot:get_name()~=stack:get_name() then
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
local output,after=minetest.get_craft_result({
method="cooking",
width=1,
items={srcSlot}
})
if output.time>0 and inv:room_for_item("dst",output.item) then
output,after=minetest.get_craft_result({
method="fuel",
width=1,
items={fuelSlot}
})
if output.time>0 then
meta:set_float("fuelTime",output.time)
meta:set_float("maxFuelTime",output.time)
inv:set_stack("fuel",1,after.items[1])
return true
end
end
return stack:get_count()
end
return false
end
ironFurnace.allowMetadataInventoryTake=function(pos,listname,index,stack)
function industrialtest.IronFurnace.shouldDeactivate(self,pos)
local meta=minetest.get_meta(pos)
if meta:get_float("fuelTime")>0 then
return false
end
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
if listname=="src" and stack:get_count()==srcSlot:get_count() then
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
if meta:get_float("maxFuelTime")>0 then
meta:set_string("formspec",ironFurnace.getFormspec(meta:get_float("fuelTime")/meta:get_float("maxFuelTime")*100,0))
end
elseif listname=="dst" and dstSlot:get_free_space()==0 then
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
return stack:get_count()
local srcOutput,_=minetest.get_craft_result({
method="cooking",
width=1,
items={srcSlot}
})
if srcOutput.time==0 or not inv:room_for_item("dst",srcOutput.item) then
meta:set_float("srcTime",0)
return true
end
ironFurnace.onMetadataInventoryMove=function(pos,fromList,fromIndex,toList,toIndex,count)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
if fromList=="src" and count==srcSlot:get_count() then
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
if meta:get_float("maxFuelTime")>0 then
meta:set_string("formspec",ironFurnaceFormspec(meta:get_float("fuelTime")/meta:get_float("maxFuelTime")*100,0))
end
elseif fromList=="dst" and dstSlot:get_free_space()==0 then
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
local fuelSlot=inv:get_stack("fuel",1)
local fuelOutput,_=minetest.get_craft_result({
method="fuel",
width=1,
items={fuelSlot}
})
if fuelOutput.time==0 then
meta:set_float("srcTime",0)
return true
end
ironFurnace.onMetadataInventoryPut=function(pos,listname,index,stack)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false
end
local definition={
description=S("Iron Furnace"),
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_iron_furnace_front.png",
"industrialtest_machine_block.png"
},
paramtype2="facedir",
legacy_facedir_simple=true,
on_construct=ironFurnace.onConstruct,
on_timer=ironFurnace.onTimer,
allow_metadata_inventory_move=ironFurnace.allowMetadataInventoryMove,
allow_metadata_inventory_put=ironFurnace.allowMetadataInventoryPut,
allow_metadata_inventory_take=ironFurnace.allowMetadataInventoryTake,
on_metadata_inventory_move=ironFurnace.onMetadataInventoryMove,
on_metadata_inventory_put=ironFurnace.onMetadataInventoryPut
}
if industrialtest.mtgAvailable then
definition.groups={
cracky=1,
level=2
}
definition.sounds=default.node_sound_metal_defaults()
definition.can_dig=function(pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
return not (inv:get_list("src")[1]:get_count()>0 or inv:get_list("fuel")[1]:get_count()>0 or inv:get_list("dst")[1]:get_count()>0)
function industrialtest.IronFurnace.afterDeactivation(self,pos)
self:updateFormspec(pos)
end
elseif industrialtest.mclAvailable then
definition.groups={
pickaxey=1,
container=2
}
definition.after_dig_node=function(pos,oldnode,oldmeta)
industrialtest.internal.mclAfterDigNode(pos,oldmeta,{"src","fuel","dst"})
end
definition.sounds=mcl_sounds.node_sound_metal_defaults()
definition._mcl_blast_resistance=3
definition._mcl_hardness=3.5
definition._mcl_hoppers_on_try_pull = mcl_furnaces.hoppers_on_try_pull
definition._mcl_hoppers_on_try_push = mcl_furnaces.hoppers_on_try_push
definition._mcl_hoppers_on_after_push = function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
end
minetest.register_node("industrialtest:iron_furnace",definition)
definition=table.copy(definition)
definition.description=nil
definition.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_iron_furnace_front_active.png",
"industrialtest_machine_block.png"
}
definition.light_source=8
definition.drop="industrialtest:iron_furnace"
definition.on_timer=ironFurnace.activeOnTimer
if industrialtest.mclAvailable then
definition.groups={
not_in_creative_inventory=1,
pickaxey=1,
container=2
}
definition._doc_items_create_entry=false
end
minetest.register_node("industrialtest:iron_furnace_active",definition)
industrialtest.IronFurnace:register()
minetest.register_craft({
type="shaped",
output="industrialtest:iron_furnace",

View File

@ -15,18 +15,55 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.internal.registerSimpleElectricItemProcessor({
name="macerator",
displayName=S("Macerator"),
customFrontTexture=true,
industrialtest.Macerator=table.copy(industrialtest.SimpleElectricItemProcessor)
industrialtest.internal.unpackTableInto(industrialtest.Macerator,{
name="industrialtest:macerator",
description=S("Macerator"),
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_macerator_front.png"
},
requiresWrench=true,
active={
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_macerator_front_active.png"
}
},
capacity=1200,
flow=industrialtest.api.lvPowerFlow,
opPower=100,
method="industrialtest.macerating",
efficiency=1
})
function industrialtest.Macerator.getCraftResult(self,itemstack)
local output=industrialtest.api.getMaceratorRecipeResult(itemstack:get_name())
if not output then
return {
item=ItemStack(),
time=0,
src=itemstack
}
end
local srcAfter=ItemStack(itemstack:get_name())
srcAfter:set_count(itemstack:get_count()-1)
return {
item=ItemStack(output.output),
time=output.time,
src=srcAfter
}
end
industrialtest.Macerator:register()
minetest.register_craft({
type="shaped",
output="industrialtest:macerator",

329
machines/machine.lua Normal file
View File

@ -0,0 +1,329 @@
-- IndustrialTest
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
industrialtest.Machine={}
function industrialtest.Machine.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
if not self.withoutFormspec then
meta:set_string("formspec",self:getFormspec(pos))
end
self:trigger(pos)
end
function industrialtest.Machine.onDestruct(self)
-- dummy function
end
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.onDig(self,pos,node,digger)
-- dummy function
return minetest.node_dig(pos,node,digger)
end
function industrialtest.Machine.getFormspec(self,pos)
local formspec
if industrialtest.mtgAvailable then
formspec={
"formspec_version[4]",
"size[10.8,12]",
"label[0.5,0.5;"..self.description.."]",
"list[current_player;main;0.5,6.25;8,1]",
"list[current_player;main;0.5,7.5;8,3;8]",
"listring[current_player;main]"
}
elseif industrialtest.mclAvailable then
formspec={
"size[10.04,12]",
"label[0.25,0.25;"..self.description.."]",
"list[current_player;main;0.5,7;9,3;9]",
mcl_formspec.get_itemslot_bg(0.5,7,9,3),
"list[current_player;main;0.5,10.24;9,1]",
mcl_formspec.get_itemslot_bg(0.5,10.24,9,1),
"listring[current_player;main]"
}
end
return table.concat(formspec,"")
end
function industrialtest.Machine.updateFormspec(self,pos)
if self.withoutFormspec then
return
end
local meta=minetest.get_meta(pos)
meta:set_string("formspec",self:getFormspec(pos))
end
function industrialtest.Machine.canUpdate(self,pos)
return false
end
function industrialtest.Machine.trigger(self,pos)
local timer=minetest.get_node_timer(pos)
if not timer:is_started() then
timer:start(industrialtest.config.updateDelay)
end
end
function industrialtest.Machine.triggerIfNeeded(self,pos)
if self:canUpdate(pos) then
self:trigger(pos)
end
end
function industrialtest.Machine.onTimer(self,pos,elapsed)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local shouldRerunTimer=false
local shouldUpdateFormspec=false
if self.update then
shouldRerunTimer,shouldUpdateFormspec=self:update(pos,elapsed,meta,inv)
end
if shouldUpdateFormspec then
self:updateFormspec(pos)
end
return shouldRerunTimer
end
function industrialtest.Machine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local movedItemStack=inv:get_stack(fromList,1)
if toList=="upgrades" then
return self.allowMoveToUpgradeSlot(pos,toIndex,movedItemStack)
end
return count
end
function industrialtest.Machine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
if listname=="upgrades" then
return self.allowMoveToUpgradeSlot(pos,index,stack)
end
return stack:get_count()
end
function industrialtest.Machine.allowMetadataInventoryTake(self,pos,listname,index,stack,player)
return stack:get_count()
end
function industrialtest.Machine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
if toList=="upgrades" then
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local itemstack=inv:get_stack(fromList,fromIndex)
local def=itemstack:get_definition()
if def and def._industrialtest_self and def._industrialtest_self.apply then
def._industrialtest_self:apply(pos)
end
elseif fromList=="upgrades" then
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local itemstack=inv:get_stack(fromList,fromIndex)
local def=itemstack:get_definition()
if def and def._industrialtest_self and def._industrialtest_self.remove then
def._industrialtest_self:remove(pos)
end
end
end
function industrialtest.Machine.onMetadataInventoryPut(self,pos,listname,index,stack)
if listname=="upgrades" then
local def=stack:get_definition()
if def and def._industrialtest_self and def._industrialtest_self.apply then
def._industrialtest_self:apply(pos)
end
end
end
function industrialtest.Machine.onMetadataInventoryTake(self,pos,listname,index,stack)
if listname=="upgrades" then
local def=stack:get_definition()
if def and def._industrialtest_self and def._industrialtest_self.remove then
def._industrialtest_self:remove(pos)
end
end
end
function industrialtest.Machine.onReceiveFields(self,pos,formname,fields)
-- dummy function
end
local function mclAfterDigNode(pos,oldmeta,lists)
-- Taken from https://git.minetest.land/MineClone2/MineClone2/src/branch/master/mods/ITEMS/mcl_furnaces/init.lua#L538
local meta=minetest.get_meta(pos)
local meta2=meta
meta:from_table(oldmeta)
local inv=meta:get_inventory()
for _,listname in ipairs(lists) do
local stack=inv:get_stack(listname,1)
if not stack:is_empty() then
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5}
minetest.add_item(p, stack)
end
end
meta:from_table(meta2:to_table())
end
function industrialtest.Machine.createDefinitionTable(self)
local def={
description=self.description,
tiles=self.tiles,
on_construct=function(pos)
self:onConstruct(pos)
end,
on_destruct=function(pos)
self:onDestruct(pos)
end,
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_dig=function(pos,node,digger)
return self:onDig(pos,node,digger)
end,
on_timer=function(pos,elapsed)
return self:onTimer(pos,elapsed)
end,
allow_metadata_inventory_move=function(pos,fromList,fromIndex,toList,toIndex,count)
return self:allowMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex,count)
end,
allow_metadata_inventory_put=function(pos,listname,index,stack,player)
return self:allowMetadataInventoryPut(pos,listname,index,stack,player)
end,
allow_metadata_inventory_take=function(pos,listname,index,stack,player)
return self:allowMetadataInventoryTake(pos,listname,index,stack,player)
end,
on_metadata_inventory_put=function(pos,listname,index,stack,player)
self:onMetadataInventoryPut(pos,listname,index,stack)
end,
on_metadata_inventory_move=function(pos,fromList,fromIndex,toList,toIndex,count)
self:onMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex)
end,
on_metadata_inventory_take=function(pos,listname,index,stack,player)
self:onMetadataInventoryTake(pos,listname,index,stack)
end,
on_receive_fields=function(pos,formname,fields)
self:onReceiveFields(pos,formname,fields)
end,
_industrialtest_self=self
}
if industrialtest.mtgAvailable then
def.groups={cracky=2}
if self.sounds=="metal" then
def.sounds=default.node_sound_metal_defaults()
elseif self.sounds=="wood" then
def.sounds=default.node_sound_wood_defaults()
end
def.can_dig=function(pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
for _,value in ipairs(self.storageLists) do
if inv:get_stack(value,1):get_count()>0 then
return false
end
end
return true
end
elseif industrialtest.mclAvailable then
def.after_dig_node=function(pos,oldnode,oldmeta)
mclAfterDigNode(pos,oldmeta,self.storageLists)
end
if self.sounds=="metal" then
def.sounds=mcl_sounds.node_sound_metal_defaults()
elseif sounds=="wood" then
def.sounds=mcl_sounds.node_sound_wood_defaults()
end
def.groups={
pickaxey=1,
container=2
}
def._mcl_blast_resistance=3.5
def._mcl_hardness=3.9
def._mcl_hoppers_on_try_pull=function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack("dst", 1)
if not stack:is_empty() and hop_inv:room_for_item(hop_list, stack) then
return inv, "dst", 1
end
return nil, nil, nil
end
def._mcl_hoppers_on_try_push=function(pos, hop_pos, hop_inv, hop_list)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv, "src", mcl_util.select_stack(hop_inv, hop_list, inv, "src")
end
def._mcl_hoppers_on_after_push=function(pos)
self:triggerIfNeeded(pos)
end
end
def.groups._industrialtest_wrenchUnmountable=1
if self.requiresWrench then
def.drop="industrialtest:machine_block"
end
if self.facedir then
def.paramtype2="facedir"
def.legacy_facedir_simple=true
end
if self.hasPowerInput then
def.groups._industrialtest_hasPowerInput=1
end
if self.hasPowerOutput then
def.groups._industrialtest_hasPowerOutput=1
end
return def
end
function industrialtest.Machine.register(self)
local def=self:createDefinitionTable()
minetest.register_node(self.name,def)
industrialtest.api.addTag(self.name,"usesTimer")
end
function industrialtest.Machine.allowMoveToUpgradeSlot(pos,toIndex,itemstack)
local def=itemstack:get_definition()
if not def or not def.groups or not def.groups._industrialtest_machineUpgrade then
return 0
end
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local targetSlot=inv:get_stack("upgrades",toIndex)
if not targetSlot:is_empty() then
return 0
end
return itemstack:get_count()
end

View File

@ -15,20 +15,54 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local massFabricator={}
industrialtest.internal.registerSimpleElectricItemProcessor({
name="mass_fabricator",
displayName=S("Mass Fabricator"),
capacity=100000,
industrialtest.MassFabricator=table.copy(industrialtest.SimpleElectricItemProcessor)
industrialtest.internal.unpackTableInto(industrialtest.MassFabricator,{
name="industrialtest:mass_fabricator",
description=S("Mass Fabricator"),
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_mass_fabricator_front.png"
},
requiresWrench=true,
active={
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_mass_fabricator_front_active.png"
}
},
capacity=100000,
flow=industrialtest.api.evPowerFlow,
opPower=10000,
machineBlockTexture="industrialtest_advanced_machine_block.png",
customFrontTexture=true,
method="industrialtest.mass_fabricating",
efficiency=1
})
function industrialtest.MassFabricator.getCraftResult(self,itemstack)
if itemstack:get_count()<34 or itemstack:get_name()~="industrialtest:scrap" then
return {
item=ItemStack(),
time=0,
src=itemstack
}
end
local srcAfter=ItemStack(itemstack:get_name())
srcAfter:set_count(itemstack:get_count()-34)
return {
item=ItemStack("industrialtest:uu_matter"),
time=15,
src=srcAfter
}
end
industrialtest.MassFabricator:register()
minetest.register_craft({
type="shaped",
output="industrialtest:mass_fabricator",

388
machines/miner.lua Normal file
View File

@ -0,0 +1,388 @@
-- 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 <http://www.gnu.org/licenses/>.
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,
_scannerOpPower=10
})
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.onDig(self,pos,node,digger)
destructMiningPipe(vector.new(pos.x,pos.y-1,pos.z),digger)
return industrialtest.ElectricMachine.onDig(self,pos,node,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),
"listring[context;src]",
"listring[context;dst]"
}
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")
local requiredPower=self:getRequiredPower(pos)
return meta:get_int("industrialtest.powerAmount")>=requiredPower 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,itemstack,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)
local scannerSlot=inv:get_stack("scanner",1)
if not scannerSlot:is_empty() then
local def=scannerSlot:get_definition()
if def and def._industrialtest_self then
local filtered=def._industrialtest_self:filter(targetPos)
for _,filteredPos in ipairs(filtered) do
drop=self.getNodeDrop(filteredPos)
if inv:room_for_item("dst",drop) then
minetest.remove_node(filteredPos)
inv:add_item("dst",drop)
end
end
end
end
local requiredPower=self:getRequiredPower(pos)
meta:set_int("level",level-1)
industrialtest.api.addPower(meta,-requiredPower)
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.getRequiredPower(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local scannerSlot=inv:get_stack("scanner",1)
local result=self._opPower
if not scannerSlot:is_empty() then
local def=scannerSlot:get_definition()
if def and def._industrialtest_self then
local distance=def._industrialtest_self.minerDistance or 0
result=result+(distance*distance-1)*self._scannerOpPower
end
end
return result
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",""}
}
})

View File

@ -15,10 +15,72 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local reactor={}
local reactorChamber={}
industrialtest.Reactor=table.copy(industrialtest.ActivatedElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.Reactor,{
name="industrialtest:nuclear_reactor",
description=S("Nuclear Reactor"),
tiles={
"industrialtest_machine_block.png^industrialtest_nuclear_reactor_top.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png^industrialtest_nuclear_reactor_front.png"
},
sounds="metal",
requiresWrench=true,
facedir=true,
storageLists={
"charged",
"fuel"
},
powerLists={
{
list="charged",
direction="o"
}
},
active={
tiles={
"industrialtest_machine_block.png^industrialtest_nuclear_reactor_top.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png^industrialtest_nuclear_reactor_front_active.png"
},
lightSource=2
},
capacity=industrialtest.api.evPowerFlow,
flow=industrialtest.api.evPowerFlow,
hasPowerOutput=true,
ioConfig="oooooo"
})
reactor.getFormspec=function(pos)
function industrialtest.Reactor.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("fuel",4)
inv:set_size("charged",1)
meta:set_int("heat",0)
meta:set_int("size",6)
meta:set_int("enabled",0)
meta:set_int("stateChanged",0)
industrialtest.ActivatedElectricMachine.onConstruct(self,pos)
end
function industrialtest.Reactor.onDestruct(self,pos)
local meta=minetest.get_meta(pos)
local chambers=minetest.deserialize(meta:get_string("chambers")) or {}
for _,chamber in ipairs(chambers) do
minetest.remove_node(chamber)
minetest.add_item(chamber,"industrialtest:nuclear_reactor_chamber")
end
industrialtest.ActivatedElectricMachine.onDestruct(self,pos)
end
function industrialtest.Reactor.getFormspec(self,pos)
local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local charged=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")
local size=math.floor(meta:get_int("size")/3)
@ -29,32 +91,158 @@ reactor.getFormspec=function(pos)
"list[context;charged;7,2.8;1,1]",
industrialtest.internal.getItemSlotBg(7.7,2.8,1,1),
"button[7.7,1;1,0.8;toggle;"..minetest.formspec_escape(switchText).."]",
"box[9,1;0.3,4.8;#202020]",
(charged>0 and "box[9,"..(1+4.8-(charged*4.8))..";0.3,"..(charged*4.8)..";#FF1010]" or ""),
self.createPowerIndicatorWidget(charged,9,1),
"listring[context;fuel]"
}
return table.concat(formspec,"")
return parentFormspec..table.concat(formspec,"")
end
reactor.onConstruct=function(pos,meta,inv)
inv:set_size("fuel",4)
inv:set_size("charged",1)
meta:set_int("heat",0)
meta:set_int("size",6)
meta:set_int("enabled",0)
meta:set_int("stateChanged",0)
end
reactor.onDestruct=function(pos)
function industrialtest.Reactor.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
local meta=minetest.get_meta(pos)
local chambers=minetest.deserialize(meta:get_string("chambers")) or {}
for _,chamber in ipairs(chambers) do
minetest.remove_node(chamber)
minetest.add_item(chamber,"industrialtest:nuclear_reactor_chamber")
local inv=meta:get_inventory()
local movedItemStack=inv:get_stack(fromList,fromIndex)
local def=movedItemStack:get_definition()
if toList=="fuel" and (not def or not def.groups._industrialtest_placedInNuclearReactor) then
return 0
end
return industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
local function hasFuel(fuelList)
function industrialtest.Reactor.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
local def=stack:get_definition()
if listname=="fuel" and (not def or not def.groups._industrialtest_placedInNuclearReactor) then
return 0
end
return industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
end
function industrialtest.Reactor.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
industrialtest.ActivatedElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
self.synchronizeChambers(pos)
end
function industrialtest.Reactor.onMetadataInventoryPut(self,pos,listname,index,stack,player)
industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
self.synchronizeChambers(pos)
end
function industrialtest.Reactor.onMetadataInventoryTake(self,pos,listname,index,stack)
industrialtest.ActivatedElectricMachine.onMetadataInventoryTake(self,pos,listname,index,stack)
self.synchronizeChambers(pos)
end
function industrialtest.Reactor.onReceiveFields(self,pos,formname,fields)
if not fields.toggle then
return
end
local meta=minetest.get_meta(pos)
if not self.hasFuel(pos) and meta:get_int("enabled")==0 then
return
end
if meta:get_int("enabled")==0 then
meta:set_int("enabled",1)
else
meta:set_int("enabled",0)
self:updateFormspec(pos)
self.synchronizeChambers(pos)
end
meta:set_int("stateChanged",1)
self:triggerIfNeeded(pos)
end
function industrialtest.Reactor.shouldActivate(self,pos)
local meta=minetest.get_meta(pos)
if meta:get_int("stateChanged")==0 then
return false
end
return meta:get_int("enabled")>0 and self.hasFuel(pos)
end
function industrialtest.Reactor.shouldDeactivate(self,pos)
local meta=minetest.get_meta(pos)
return meta:get_int("enabled")==0 or not self.hasFuel(pos)
end
function industrialtest.Reactor.afterActivation(self,pos)
local meta=minetest.get_meta(pos)
meta:set_int("stateChanged",0)
self.synchronizeChambers(pos)
end
function industrialtest.Reactor.afterDeactivation(self,pos)
local meta=minetest.get_meta(pos)
meta:set_int("enabled",0)
self:updateFormspec(pos)
self.synchronizeChambers(pos)
end
function industrialtest.Reactor.activeUpdate(self,pos,elapsed,meta,inv)
local size=math.floor(meta:get_int("size")/3)
local fuelList=inv:get_list("fuel")
local shouldRerunTimer=meta:get_int("enabled")>0
local shouldUpdateFormspec=false
local maxCluster=self.findMaxFuelCluster(size,fuelList)
for _,stack in ipairs(maxCluster) do
local index=stack.y*size+stack.x
local usedStack,_=self.useFuel(fuelList[index],5)
inv:set_stack("fuel",index,usedStack)
end
local generatedPowerAmount=math.pow(3,#maxCluster)
if industrialtest.api.addPower(meta,generatedPowerAmount)>0 then
shouldUpdateFormspec=true
end
local heat=meta:get_int("heat")+#maxCluster
local coolant=self.findCoolant(fuelList)
if coolant>0 then
local coolantStack,used=self.useFuel(fuelList[coolant],#maxCluster*50)
heat=math.max(0,heat-used)
inv:set_stack("fuel",coolant,coolantStack)
end
if heat>200 then
minetest.remove_node(pos)
industrialtest.internal.explode(pos,#maxCluster*4)
return false
end
meta:set_int("heat",heat)
self.synchronizeChambers(pos)
return shouldUpdateFormspec
end
function industrialtest.Reactor.changeSize(self,pos,diff)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local size=meta:get_int("size")+diff
local actualSize=math.floor(size/3)
meta:set_int("size",size)
inv:set_size("fuel",actualSize*actualSize)
self:updateFormspec(pos)
end
function industrialtest.Reactor.synchronizeToChamber(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local fuelList=inv:get_list("fuel")
local chargedList=inv:get_list("charged")
local reactorPos=minetest.deserialize(meta:get_string("reactor"))
local reactorMeta=minetest.get_meta(reactorPos)
local reactorInv=reactorMeta:get_inventory()
reactorInv:set_list("fuel",fuelList)
reactorInv:set_list("charged",chargedList)
self.synchronizeChambers(reactorPos)
end
function industrialtest.Reactor.hasFuel(pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local fuelList=inv:get_list("fuel")
for _,stack in ipairs(fuelList) do
if stack:get_name()=="industrialtest:uranium_cell" then
return true
@ -63,7 +251,7 @@ local function hasFuel(fuelList)
return false
end
local function findMaxFuelCluster(size,fuelList)
function industrialtest.Reactor.findMaxFuelCluster(size,fuelList)
local maxCluster={}
for y=1,size do
for x=1,size do
@ -137,7 +325,7 @@ local function findMaxFuelCluster(size,fuelList)
return maxCluster
end
local function findCoolant(fuelList)
function industrialtest.Reactor.findCoolant(fuelList)
for i=1,#fuelList do
local stack=fuelList[i]
local def=minetest.registered_tools[stack:get_name()]
@ -148,7 +336,7 @@ local function findCoolant(fuelList)
return 0
end
local function useFuel(stack,use)
function industrialtest.Reactor.useFuel(stack,use)
local used=math.min(65535-stack:get_wear(),use)
if used<use then
stack:replace("industrialtest:empty_cell")
@ -158,197 +346,67 @@ local function useFuel(stack,use)
return stack,used
end
reactor.onTimer=function(pos,elapsed,meta,inv)
local powerFlow=meta:get_int("industrialtest.powerFlow")
local chargedSlot=inv:get_stack("charged",1)
local fuelList=inv:get_list("fuel")
local afterFlow,flowTransferred=industrialtest.api.powerFlow(pos)
local shouldRerunTimer=meta:get_int("enabled")>0
local shouldUpdateFormspec=false
if chargedSlot:get_count()>0 and not industrialtest.api.isFullyCharged(chargedSlot:get_meta()) and meta:get_int("industrialtest.powerAmount")>0 then
industrialtest.api.transferPowerToItem(meta,chargedSlot,powerFlow)
inv:set_stack("charged",1,chargedSlot)
shouldUpdateFormspec=true
shouldRerunTimer=true
end
if meta:get_int("stateChanged")>0 then
shouldUpdateFormspec=true
meta:set_int("stateChanged",0)
end
if meta:get_int("enabled")>0 and hasFuel(fuelList) then
minetest.swap_node(pos,{
name="industrialtest:nuclear_reactor_active",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
shouldRerunTimer=false
end
reactor.synchronizeChambers(pos)
return shouldRerunTimer,shouldUpdateFormspec
end
reactor.activeOnTimer=function(pos,elapsed,meta,inv)
local powerFlow=meta:get_int("industrialtest.powerFlow")
local size=math.floor(meta:get_int("size")/3)
local chargedSlot=inv:get_stack("charged",1)
local fuelList=inv:get_list("fuel")
local afterFlow,flowTransferred=industrialtest.api.powerFlow(pos)
local shouldRerunTimer=meta:get_int("enabled")>0
local shouldUpdateFormspec=false
if chargedSlot:get_count()>0 and not industrialtest.api.isFullyCharged(chargedSlot:get_meta()) and meta:get_int("industrialtest.powerAmount")>0 then
industrialtest.api.transferPowerToItem(meta,chargedSlot,powerFlow)
inv:set_stack("charged",1,chargedSlot)
shouldUpdateFormspec=true
shouldRerunTimer=true
end
if meta:get_int("stateChanged")>0 then
shouldUpdateFormspec=true
meta:set_int("stateChanged",0)
end
if meta:get_int("enabled")==0 or not hasFuel(fuelList) then
minetest.swap_node(pos,{
name="industrialtest:nuclear_reactor",
param2=minetest.get_node(pos).param2
})
meta:set_int("enabled",0)
reactor.synchronizeChambers(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false,shouldUpdateFormspec
end
local maxCluster=findMaxFuelCluster(size,fuelList)
for _,stack in ipairs(maxCluster) do
local index=stack.y*size+stack.x
local usedStack,_=useFuel(fuelList[index],5)
inv:set_stack("fuel",index,usedStack)
end
local generatedPowerAmount=math.pow(3,#maxCluster)
if industrialtest.api.addPower(meta,generatedPowerAmount)>0 then
shouldUpdateFormspec=true
end
local heat=meta:get_int("heat")+#maxCluster
local coolant=findCoolant(fuelList)
if coolant>0 then
local coolantStack,used=useFuel(fuelList[coolant],#maxCluster*50)
heat=math.max(0,heat-used)
inv:set_stack("fuel",coolant,coolantStack)
end
if heat>200 then
minetest.remove_node(pos)
industrialtest.internal.explode(pos,#maxCluster*4)
return false,false
end
meta:set_int("heat",heat)
reactor.synchronizeChambers(pos)
return shouldRerunTimer,shouldUpdateFormspec
end
reactor.allowMetadataInventoryMove=function(pos,fromList,fromIndex,toList,toIndex,count)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local movedItemStack=inv:get_stack(fromList,fromIndex)
local def=minetest.registered_tools[movedItemStack:get_name()]
if toList=="fuel" and (not def or not def.groups._industrialtest_placedInNuclearReactor) then
return 0
end
return count
end
reactor.allowMetadataInventoryPut=function(pos,listname,index,stack)
local def=minetest.registered_tools[stack:get_name()]
if listname=="fuel" and (not def or not def.groups._industrialtest_placedInNuclearReactor) then
return 0
end
return stack:get_count()
end
reactor.metadataChange=function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
reactor.synchronizeChambers(pos)
end
reactor.handleFormspecFields=function(pos,formname,fields)
if not fields.toggle then
return
end
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local fuelList=inv:get_list("fuel")
if not hasFuel(fuelList) and meta:get_int("enabled")==0 then
return
end
if meta:get_int("enabled")==0 then
meta:set_int("enabled",1)
else
meta:set_int("enabled",0)
end
meta:set_int("stateChanged",1)
reactor.metadataChange(pos)
end
reactor.synchronizeToChamber=function(pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local fuelList=inv:get_list("fuel")
local chargedList=inv:get_list("charged")
local reactorPos=minetest.deserialize(meta:get_string("reactor"))
local reactorMeta=minetest.get_meta(reactorPos)
local reactorInv=reactorMeta:get_inventory()
reactorInv:set_list("fuel",fuelList)
reactorInv:set_list("charged",chargedList)
reactor.synchronizeChambers(reactorPos)
end
reactor.synchronizeChambers=function(pos)
function industrialtest.Reactor.synchronizeChambers(pos)
local meta=minetest.get_meta(pos)
local chambers=meta:contains("chambers") and minetest.deserialize(meta:get_string("chambers")) or {}
for _,chamber in ipairs(chambers) do
reactorChamber.synchronize(chamber,pos)
industrialtest.ReactorChamber:synchronize(chamber,pos)
end
end
reactor.changeSize=function(pos,diff)
industrialtest.Reactor:register()
minetest.register_craft({
type="shaped",
output="industrialtest:nuclear_reactor",
recipe={
{"","industrialtest:advanced_electronic_circuit",""},
{"industrialtest:nuclear_reactor_chamber","industrialtest:nuclear_reactor_chamber","industrialtest:nuclear_reactor_chamber"},
{"","industrialtest:generator",""}
}
})
industrialtest.ReactorChamber=table.copy(industrialtest.Machine)
industrialtest.internal.unpackTableInto(industrialtest.ReactorChamber,{
name="industrialtest:nuclear_reactor_chamber",
description=S("Nuclear Reactor Chamber"),
tiles={"industrialtest_machine_block.png^industrialtest_nuclear_reactor_top.png"},
sounds="metal",
storageLists={
"charged",
"fuel"
},
requiresWrench=true
})
function industrialtest.ReactorChamber.onDestruct(self,pos)
industrialtest.Machine.onDestruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local size=meta:get_int("size")+diff
local actualSize=math.floor(size/3)
meta:set_int("size",size)
inv:set_size("fuel",actualSize*actualSize)
local def=minetest.registered_nodes[minetest.get_node(pos).name]
def._industrialtest_updateFormspec(pos)
if not meta:contains("reactor") then
return
end
reactorChamber.synchronize=function(pos,reactor)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local reactorDef=minetest.registered_nodes[minetest.get_node(reactor).name]
meta:set_string("formspec",reactorDef._industrialtest_getFormspec(reactor))
local reactorPos=minetest.deserialize(meta:get_string("reactor"))
local reactorMeta=minetest.get_meta(reactorPos)
if not reactorMeta or not reactorMeta:contains("chambers") then
return
end
local chambers=minetest.deserialize(reactorMeta:get_string("chambers"))
for i,chamber in ipairs(chambers) do
if chamber.x==pos.x and chamber.y==pos.y and chamber.z==pos.z then
table.remove(chambers,i)
break
end
end
reactorMeta:set_string("chambers",minetest.serialize(chambers))
local reactorMeta=minetest.get_meta(reactor)
local reactorInv=reactorMeta:get_inventory()
local fuelList=reactorInv:get_list("fuel")
local chargedList=reactorInv:get_list("charged")
inv:set_size("fuel",#fuelList)
inv:set_size("charged",#chargedList)
inv:set_list("fuel",fuelList)
inv:set_list("charged",chargedList)
industrialtest.Reactor:changeSize(reactorPos,-1)
industrialtest.Reactor.synchronizeChambers(reactorPos)
end
reactorChamber.afterPlaceNode=function(pos)
function industrialtest.ReactorChamber.afterPlaceNode(self,pos)
local neighbours={
vector.offset(pos,-1,0,0),
vector.offset(pos,1,0,0),
@ -372,8 +430,8 @@ reactorChamber.afterPlaceNode=function(pos)
local meta=minetest.get_meta(pos)
meta:set_string("reactor",minetest.serialize(reactorPos))
reactor.changeSize(reactorPos,1)
reactor.synchronizeChambers(reactorPos)
industrialtest.Reactor:changeSize(reactorPos,1)
industrialtest.Reactor.synchronizeChambers(reactorPos)
local reactorMeta=minetest.get_meta(reactorPos)
local chambers=reactorMeta:contains("chambers") and minetest.deserialize(reactorMeta:get_string("chambers")) or {}
@ -382,129 +440,72 @@ reactorChamber.afterPlaceNode=function(pos)
industrialtest.api.createNetworkMapForNode(reactorPos)
reactorChamber.synchronize(pos,reactorPos)
self:synchronize(pos,reactorPos)
end
reactorChamber.onDestruct=function(pos)
function industrialtest.ReactorChamber.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
if not meta:contains("reactor") then
return
end
local reactorPos=minetest.deserialize(meta:get_string("reactor"))
local reactorMeta=minetest.get_meta(reactorPos)
if not reactorMeta or not reactorMeta:contains("chambers") then
return
end
local chambers=minetest.deserialize(reactorMeta:get_string("chambers"))
for i,chamber in ipairs(chambers) do
if chamber.x==pos.x and chamber.y==pos.y and chamber.z==pos.z then
table.remove(chambers,i)
break
end
end
reactorMeta:set_string("chambers",minetest.serialize(chambers))
reactor.changeSize(reactorPos,-1)
reactor.synchronizeChambers(reactorPos)
return ""
end
reactorChamber.handleFormspecFields=function(pos,formname,fields)
local reactorPos=minetest.deserialize(meta:get_string("reactor"))
return industrialtest.Reactor:getFormspec(reactorPos)
end
function industrialtest.ReactorChamber.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
return industrialtest.Reactor:allowMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex,count)
end
function industrialtest.ReactorChamber.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
return industrialtest.Reactor:allowMetadataInventoryPut(pos,listname,index,stack,player)
end
function industrialtest.ReactorChamber.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
industrialtest.Machine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
industrialtest.Reactor:synchronizeToChamber(pos)
end
function industrialtest.ReactorChamber.onMetadataInventoryPut(self,pos,listname,index,stack,player)
industrialtest.Machine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
industrialtest.Reactor:synchronizeToChamber(pos)
end
function industrialtest.ReactorChamber.onMetadataInventoryTake(self,pos,listname,index,stack)
industrialtest.Machine.onMetadataInventoryTake(self,pos,listname,index,stack)
industrialtest.Reactor:synchronizeToChamber(pos)
end
function industrialtest.ReactorChamber.onReceiveFields(self,pos,formname,fields)
local meta=minetest.get_meta(pos)
local reactorPos=minetest.deserialize(meta:get_string("reactor"))
reactor.handleFormspecFields(reactorPos,formname,fields)
industrialtest.Reactor:onReceiveFields(reactorPos,formname,fields)
end
industrialtest.internal.registerMachine({
name="nuclear_reactor",
displayName=S("Nuclear Reactor"),
getFormspec=reactor.getFormspec,
capacity=industrialtest.api.evPowerFlow,
flow=industrialtest.api.evPowerFlow,
ioConfig="oooooo",
requiresWrench=true,
registerActiveVariant=true,
powerSlots={"charged"},
storageSlots={"charged","fuel"},
sounds="metal",
groups={
_industrialtest_hasPowerOutput=1
},
customKeys={
tiles={
"industrialtest_machine_block.png^industrialtest_nuclear_reactor_top.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png^industrialtest_nuclear_reactor_front.png",
"industrialtest_machine_block.png"
},
paramtype2="facedir",
legacy_facedir_simple=true,
on_receive_fields=reactor.handleFormspecFields,
_industrialtest_synchronizeToChamber=reactor.synchronizeToChamber
},
activeCustomKeys={
tiles={
"industrialtest_machine_block.png^industrialtest_nuclear_reactor_top.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png^industrialtest_nuclear_reactor_front_active.png",
"industrialtest_machine_block.png"
},
light_source=2,
on_receive_fields=reactor.handleFormspecFields
},
onConstruct=reactor.onConstruct,
onDestruct=reactor.onDestruct,
onTimer=reactor.onTimer,
activeOnTimer=reactor.activeOnTimer,
allowMetadataInventoryMove=reactor.allowMetadataInventoryMove,
allowMetadataInventoryPut=reactor.allowMetadataInventoryPut,
onMetadataInventoryMove=reactor.metadataChange,
onMetadataInventoryPut=reactor.metadataChange,
onMetadataInventoryTake=reactor.metadataChange
})
minetest.register_craft({
type="shaped",
output="industrialtest:nuclear_reactor",
recipe={
{"","industrialtest:advanced_electronic_circuit",""},
{"industrialtest:nuclear_reactor_chamber","industrialtest:nuclear_reactor_chamber","industrialtest:nuclear_reactor_chamber"},
{"","industrialtest:generator",""}
}
})
local definition={
description=S("Nuclear Reactor Chamber"),
tiles={"industrialtest_machine_block.png^industrialtest_nuclear_reactor_top.png"},
drop="industrialtest:machine_block",
groups={
_industrialtest_wrenchUnmountable=1,
_industrialtest_cable=1
},
on_destruct=reactorChamber.onDestruct,
after_place_node=reactorChamber.afterPlaceNode,
can_dig=minetest.registered_nodes["industrialtest:nuclear_reactor"].can_dig,
on_receive_fields=reactorChamber.handleFormspecFields,
allow_metadata_inventory_move=minetest.registered_nodes["industrialtest:nuclear_reactor"].allow_metadata_inventory_move,
allow_metadata_inventory_put=minetest.registered_nodes["industrialtest:nuclear_reactor"].allow_metadata_inventory_put,
on_metadata_inventory_move=reactor.synchronizeToChamber,
on_metadata_inventory_put=reactor.synchronizeToChamber,
on_metadata_inventory_take=reactor.synchronizeToChamber,
_industrialtest_cableFlow=industrialtest.api.evPowerFlow
}
if industrialtest.mtgAvailable then
definition.sounds=default.node_sound_metal_defaults()
definition.groups.cracky=1
definition.groups.level=2
elseif industrialtest.mclAvailable then
definition.sounds=mcl_sounds.node_sound_metal_defaults()
definition._mcl_blast_resistance=6
definition._mcl_hardness=5
function industrialtest.ReactorChamber.createDefinitionTable(self)
local def=industrialtest.Machine.createDefinitionTable(self)
def.groups._industrialtest_cable=1
def._industrialtest_cableFlow=industrialtest.api.evPowerFlow
return def
end
minetest.register_node("industrialtest:nuclear_reactor_chamber",definition)
function industrialtest.ReactorChamber.synchronize(self,pos,reactor)
self:updateFormspec(pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local reactorMeta=minetest.get_meta(reactor)
local reactorInv=reactorMeta:get_inventory()
local fuelList=reactorInv:get_list("fuel")
local chargedList=reactorInv:get_list("charged")
inv:set_size("fuel",#fuelList)
inv:set_size("charged",#chargedList)
inv:set_list("fuel",fuelList)
inv:set_list("charged",chargedList)
end
industrialtest.ReactorChamber:register()
minetest.register_craft({
type="shaped",
output="industrialtest:nuclear_reactor_chamber",

View File

@ -15,9 +15,38 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local powerStorage={}
industrialtest.PowerStorage=table.copy(industrialtest.ElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.PowerStorage,{
facedir=true,
storageLists={
"charged",
"discharged"
},
powerLists={
{
list="charged",
direction="o"
},
{
list="discharged",
direction="i"
}
},
hasPowerInput=true,
hasPowerOutput=true,
ioConfig="iiiioi"
})
powerStorage.getFormspec=function(pos)
function industrialtest.PowerStorage.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("charged",1)
inv:set_size("discharged",1)
industrialtest.ElectricMachine.onConstruct(self,pos)
end
function industrialtest.PowerStorage.getFormspec(self,pos)
local parentFormspec=industrialtest.ElectricMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local charged=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")
local formspec={
@ -27,95 +56,32 @@ powerStorage.getFormspec=function(pos)
"list[context;discharged;3,2.5;1,1]",
industrialtest.internal.getItemSlotBg(3,2.5,1,1),
"label[2.7,3.9;"..S("Discharge").."]",
"box[9,1;0.3,4.8;#202020]",
(charged>0 and "box[9,"..(1+4.8-(charged*4.8))..";0.3,"..(charged*4.8)..";#FF1010]" or ""),
self.createPowerIndicatorWidget(charged,9,1),
"listring[context;charged]",
"listring[context;discharged]"
}
return table.concat(formspec,"")
return parentFormspec..table.concat(formspec,"")
end
powerStorage.onConstruct=function(pos,meta,inv)
inv:set_size("charged",1)
inv:set_size("discharged",1)
end
powerStorage.onTimer=function(pos,elapsed,meta,inv,config)
local chargedSlot=inv:get_stack("charged",1)
local dischargedSlot=inv:get_stack("discharged",1)
local afterFlow,flowTransferred=industrialtest.api.powerFlow(pos)
local shouldUpdateFormspec=flowTransferred
local shouldRerunTimer=(afterFlow and meta:get_int("industrialtest.powerAmount")>0)
if chargedSlot:get_count()>0 and meta:get_int("industrialtest.powerAmount")>0 and industrialtest.api.transferPowerToItem(meta,chargedSlot,config.flow)>0 then
inv:set_stack("charged",1,chargedSlot)
shouldRerunTimer=true
shouldUpdateFormspec=true
end
if dischargedSlot:get_count()>0 and not industrialtest.api.isFullyCharged(meta) and industrialtest.api.transferPowerFromItem(dischargedSlot,meta,config.flow)>0 then
inv:set_stack("discharged",1,dischargedSlot)
shouldRerunTimer=true
shouldUpdateFormspec=true
end
return shouldRerunTimer,shouldUpdateFormspec
end
powerStorage.onMetadataInventoryPut=function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
powerStorage.onMetadataInventoryMove=function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
local function registerPowerStorageNode(config)
industrialtest.internal.registerMachine({
name=config.name,
displayName=config.displayName,
capacity=config.capacity,
flow=config.flow,
ioConfig="iiiioi",
sounds=config.sounds,
powerSlots={"charged","discharged"},
storageSlots={"charged","discharged"},
registerActiveVariant=false,
groups={
_industrialtest_hasPowerOutput=1,
_industrialtest_hasPowerInput=1
},
customKeys={
industrialtest.BatBox=table.copy(industrialtest.PowerStorage)
industrialtest.internal.unpackTableInto(industrialtest.BatBox,{
name="industrialtest:batbox",
description=S("BatBox"),
tiles={
config.machineBlockTexture,
config.machineBlockTexture,
config.machineBlockTexture,
config.machineBlockTexture,
config.machineBlockTexture,
config.machineBlockTexture.."^industrialtest_"..config.name.."_front.png"
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png",
"industrialtest_wood_machine_block.png^industrialtest_batbox_front.png"
},
paramtype2="facedir",
legacy_facedir_simple=true
},
requiresWrench=config.requiresWrench,
getFormspec=powerStorage.getFormspec,
onConstruct=powerStorage.onConstruct,
onTimer=function(pos,elapsed,meta,inv)
return powerStorage.onTimer(pos,elapsed,meta,inv,config)
end,
onMetadataInventoryPut=powerStorage.onMetadataInventoryPut,
onMetadataInventoryMove=powerStorage.onMetadataInventoryMove
})
end
registerPowerStorageNode({
name="batbox",
displayName=S("BatBox"),
capacity=25000,
flow=industrialtest.api.lvPowerFlow,
sounds="wood",
machineBlockTexture="industrialtest_wood_machine_block.png",
requiresWrench=false
capacity=25000,
flow=industrialtest.api.lvPowerFlow
})
industrialtest.BatBox:register()
minetest.register_craft({
type="shaped",
output="industrialtest:batbox",
@ -126,15 +92,25 @@ minetest.register_craft({
}
})
registerPowerStorageNode({
name="cesu",
displayName=S("CESU"),
capacity=400000,
flow=industrialtest.api.mvPowerFlow,
industrialtest.CESU=table.copy(industrialtest.PowerStorage)
industrialtest.internal.unpackTableInto(industrialtest.CESU,{
name="industrialtest:cesu",
description=S("CESU"),
tiles={
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png",
"industrialtest_bronze_machine_block.png^industrialtest_cesu_front.png"
},
sounds="metal",
machineBlockTexture="industrialtest_bronze_machine_block.png",
requiresWrench=false
capacity=400000,
flow=industrialtest.api.mvPowerFlow
})
industrialtest.CESU:register()
minetest.register_craft({
type="shaped",
output="industrialtest:cesu",
@ -145,15 +121,26 @@ minetest.register_craft({
}
})
registerPowerStorageNode({
name="mfe",
displayName=S("MFE"),
capacity=3000000,
flow=industrialtest.api.hvPowerFlow,
industrialtest.MFE=table.copy(industrialtest.PowerStorage)
industrialtest.internal.unpackTableInto(industrialtest.MFE,{
name="industrialtest:mfe",
description=S("MFE"),
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_mfe_front.png"
},
sounds="metal",
machineBlockTexture="industrialtest_machine_block.png",
requiresWrench=true
requiresWrench=true,
capacity=3000000,
flow=industrialtest.api.hvPowerFlow
})
industrialtest.MFE:register()
minetest.register_craft({
type="shaped",
output="industrialtest:mfe",
@ -164,15 +151,27 @@ minetest.register_craft({
}
})
registerPowerStorageNode({
name="mfsu",
displayName=S("MFSU"),
capacity=30000000,
flow=industrialtest.api.evPowerFlow,
industrialtest.MFSU=table.copy(industrialtest.PowerStorage)
industrialtest.internal.unpackTableInto(industrialtest.MFSU,{
name="industrialtest:mfsu",
description=S("MFSU"),
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_mfsu_front.png"
},
sounds="metal",
machineBlockTexture="industrialtest_advanced_machine_block.png",
requiresWrench=false
requiresWrench=true,
capacity=30000000,
flow=industrialtest.api.evPowerFlow
})
industrialtest.MFSU:register()
minetest.register_craft({
type="shaped",
output="industrialtest:mfsu",

View File

@ -15,18 +15,47 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.internal.registerSimpleElectricItemProcessor({
name="recycler",
displayName=S("Recycler"),
customTopTexture=true,
industrialtest.Recycler=table.copy(industrialtest.SimpleElectricItemProcessor)
industrialtest.internal.unpackTableInto(industrialtest.Recycler,{
name="industrialtest:recycler",
description=S("Recycler"),
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_recycler_front.png"
},
requiresWrench=true,
active={
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_recycler_front_active.png"
}
},
capacity=80,
flow=industrialtest.api.lvPowerFlow,
opPower=40,
method="industrialtest.recycling",
efficiency=1
})
function industrialtest.Recycler.getCraftResult(self,itemstack)
local srcAfter=ItemStack(itemstack:get_name())
srcAfter:set_count(itemstack:get_count()-1)
return {
item=ItemStack(industrialtest.random:next(1,8)==1 and "industrialtest:scrap" or ""),
time=2,
src=srcAfter
}
end
industrialtest.Recycler:register()
minetest.register_craft({
type="shaped",
output="industrialtest:recycler",

View File

@ -15,12 +15,68 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.RotaryMacerator=table.copy(industrialtest.ActivatedElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.RotaryMacerator,{
name="industrialtest:rotary_macerator",
description=S("Rotary Macerator"),
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_macerator_front.png"
},
sounds="metal",
requiresWrench=true,
facedir=true,
storageLists={
"src",
"dst",
"upgrades",
"powerStorage"
},
powerLists={
{
list="powerStorage",
direction="i"
}
},
active={
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_macerator_front_active.png"
}
},
capacity=industrialtest.api.lvPowerFlow*2,
flow=industrialtest.api.lvPowerFlow,
hasPowerInput=true,
ioConfig="iiiiii",
_opPower=60,
_maintainSpeedOpPower=10
})
local rotaryMacerator={}
rotaryMacerator.opPower=60
rotaryMacerator.maintainSpeedOpPower=10
function industrialtest.RotaryMacerator.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("src",1)
inv:set_size("modifier",1)
inv:set_size("powerStorage",1)
inv:set_size("dst",1)
inv:set_size("upgrades",4)
meta:set_int("rpm",0)
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",0)
meta:set_int("maintainSpeed",0)
industrialtest.ActivatedElectricMachine.onConstruct(self,pos)
end
rotaryMacerator.getFormspec=function(pos)
function industrialtest.RotaryMacerator.getFormspec(self,pos)
local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local powerPercent=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")*100
local maxSrcTime=meta:get_float("maxSrcTime")
@ -47,153 +103,145 @@ rotaryMacerator.getFormspec=function(pos)
"listring[context;src]",
"listring[context;dst]"
}
return table.concat(formspec,"")
return parentFormspec..table.concat(formspec,"")
end
rotaryMacerator.onConstruct=function(pos,meta,inv)
inv:set_size("src",1)
inv:set_size("modifier",1)
inv:set_size("powerStorage",1)
inv:set_size("dst",1)
inv:set_size("upgrades",4)
meta:set_int("rpm",0)
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",0)
meta:set_int("maintainSpeed",0)
end
rotaryMacerator.onTimer=function(pos,elapsed,meta,inv)
function industrialtest.RotaryMacerator.update(self,pos,elapsed,meta,inv)
local shouldRerunTimer=false
local shouldUpdateFormspec=false
local srcSlot=inv:get_stack("src",1)
local modifierSlot=inv:get_stack("modifier",1)
local dstSlot=inv:get_stack("dst",1)
local rpm=meta:get_int("rpm")
local maintainSpeed=meta:get_int("maintainSpeed")
shouldRerunTimer,shouldUpdateFormspec=industrialtest.internal.chargeFromPowerStorageItem(meta,inv)
local powerAmount=meta:get_int("industrialtest.powerAmount")
if maintainSpeed==1 and powerAmount>=rotaryMacerator.maintainSpeedOpPower then
if maintainSpeed==1 and powerAmount>=self._maintainSpeedOpPower then
local newRpm=math.max(rpm+10*elapsed,0)
if newRpm>rpm then
meta:set_int("rpm",newRpm)
shouldUpdateFormspec=true
end
industrialtest.api.addPower(meta,-rotaryMacerator.maintainSpeedOpPower)
industrialtest.api.addPower(meta,-self._maintainSpeedOpPower)
shouldRerunTimer=true
elseif rpm>0 then
meta:set_int("rpm",math.max(rpm-1000*elapsed,0))
shouldRerunTimer=shouldRerunTimer or rpm>0
shouldRerunTimer=rpm>0
shouldUpdateFormspec=true
end
if powerAmount>=rotaryMacerator.opPower and not srcSlot:is_empty() then
local result=industrialtest.api.getMaceratorRecipeResult(srcSlot:get_name())
if result then
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",result.time)
minetest.swap_node(pos,{
name="industrialtest:rotary_macerator_active",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false,shouldUpdateFormspec
end
end
return shouldRerunTimer,shouldUpdateFormspec
end
rotaryMacerator.allowMetadataInventoryMove=function(pos,fromList,fromIndex,toList,count)
function industrialtest.RotaryMacerator.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,count)
if toList=="dst" then
return 0
end
return count
return industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
rotaryMacerator.allowMetadataInventoryPut=function(pos,listname,index,stack)
function industrialtest.RotaryMacerator.allowMetadataInventoryPut(self,pos,listname,index,stack)
if listname=="dst" then
return 0
end
return stack:get_count()
return industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack)
end
rotaryMacerator.onMetadataInventoryMove=function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
function industrialtest.RotaryMacerator.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
industrialtest.ActivatedElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
if toList=="src" or toList=="modifier" or fromList=="dst" then
self:triggerIfNeeded(pos)
end
end
rotaryMacerator.onMetadataInventoryPut=function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
function industrialtest.RotaryMacerator.onMetadataInventoryPut(self,pos,listname,index,stack,player)
industrialtest.ActivatedElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack,player)
if listname=="src" or listname=="modifier" then
self:triggerIfNeeded(pos)
end
end
rotaryMacerator.onMetadataInventoryTake=function(pos,listname)
function industrialtest.RotaryMacerator.onMetadataInventoryTake(self,pos,listname,index,stack)
industrialtest.ActivatedElectricMachine.onMetadataInventoryTake(self,pos,listname,index,stack)
if listname=="dst" then
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
self:triggerIfNeeded(pos)
end
end
rotaryMacerator.activeOnTimer=function(pos,elapsed,meta,inv)
function industrialtest.RotaryMacerator.onReceiveFields(self,pos,formname,fields)
if not fields.maintainSpeed then
return
end
local meta=minetest.get_meta(pos)
local maintainSpeed=meta:get_int("maintainSpeed")
if maintainSpeed==1 then
meta:set_int("maintainSpeed",0)
elseif meta:get_int("industrialtest.powerAmount")>=self._maintainSpeedOpPower then
meta:set_int("maintainSpeed",1)
self:trigger(pos)
end
self:updateFormspec(pos)
end
function industrialtest.RotaryMacerator.shouldActivate(self,pos)
local meta=minetest.get_meta(pos)
local powerAmount=meta:get_int("industrialtest.powerAmount")
if powerAmount<self._opPower then
return false
end
local inv=meta:get_inventory()
local result,_=self.getRecipeResult(pos)
if not result or result.time==0 or not inv:room_for_item("dst",ItemStack(result.output)) then
return false
end
return true
end
function industrialtest.RotaryMacerator.shouldDeactivate(self,pos)
return not self:shouldActivate(pos)
end
function industrialtest.RotaryMacerator.afterDeactivation(self,pos)
local meta=minetest.get_meta(pos)
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",0)
end
function industrialtest.RotaryMacerator.activeUpdate(self,pos,elapsed,meta,inv)
local srcSlot=inv:get_stack("src",1)
local modifierSlot=inv:get_stack("modifier",1)
local dstSlot=inv:get_stack("dst",1)
local powerAmount=meta:get_int("industrialtest.powerAmount")
local rpm=meta:get_int("rpm")
local maxSrcTime=meta:get_float("maxSrcTime")
local speed=industrialtest.api.getMachineSpeed(meta)
local requiredPower=elapsed*rotaryMacerator.opPower*speed
local requiredPower=elapsed*self._opPower*speed
industrialtest.internal.chargeFromPowerStorageItem(meta,inv)
if srcSlot:is_empty() or powerAmount<requiredPower then
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",0)
minetest.swap_node(pos,{
name="industrialtest:rotary_macerator",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false,true
end
local result
local modified=false
if not modifierSlot:is_empty() then
result=industrialtest.api.getRotaryMaceratorModifier(srcSlot:get_name(),modifierSlot:get_name())
end
if result then
modified=true
else
result=industrialtest.api.getMaceratorRecipeResult(srcSlot:get_name())
end
local resultStack=ItemStack(result.output)
if not dstSlot:item_fits(resultStack) then
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",0)
minetest.swap_node(pos,{
name="industrialtest:rotary_macerator",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
return false,true
end
if maxSrcTime<=0 then
local result,_=self.getRecipeResult(pos)
meta:set_float("maxSrcTime",result.time)
maxSrcTime=result.time
end
local srcTime=meta:get_float("srcTime")+elapsed*(1+rpm/7500)
if srcTime>=meta:get_float("maxSrcTime") then
if srcTime>=maxSrcTime then
local result,modified=self.getRecipeResult(pos)
local resultStack=ItemStack(result.output)
local multiplier=math.min(srcSlot:get_count(),speed)
local prevCount=resultStack:get_count()
resultStack:set_count(resultStack:get_count()*multiplier)
local leftover=inv:add_item("dst",resultStack)
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",0)
srcSlot:take_item(multiplier-leftover:get_count()/prevCount)
inv:set_stack("src",1,srcSlot)
meta:set_int("rpm",math.min(rpm+750*elapsed,7500))
if modified then
local modifierSlot=inv:get_stack("modifier",1)
local modifierMeta=modifierSlot:get_meta()
local uses=result.uses
local replace=false
if modifierMeta:contains("uses") then
uses=modifierMeta:get_int("uses")
else
replace=true
end
uses=math.max(uses-1,0)
if uses==0 then
@ -205,7 +253,12 @@ rotaryMacerator.activeOnTimer=function(pos,elapsed,meta,inv)
uses=result.uses
end
if not modifierSlot:is_empty() and not result.modifierLeftover then
local modifierDef=modifierSlot:get_definition()
modifierMeta:set_int("uses",uses)
modifierMeta:set_string("description",string.format("%s (%s: %d)",modifierDef.description,S("Uses"),uses))
end
if replace then
modifierSlot:set_name(result.stackLeftover)
end
inv:set_stack("modifier",1,modifierSlot)
end
@ -215,55 +268,29 @@ rotaryMacerator.activeOnTimer=function(pos,elapsed,meta,inv)
industrialtest.api.addPower(meta,-requiredPower)
return true,true
return true
end
industrialtest.RotaryMacerator:register()
function industrialtest.RotaryMacerator.getRecipeResult(pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local modifierSlot=inv:get_stack("modifier",1)
local result
local modified=false
if modifierSlot:is_empty() then
result=industrialtest.api.getMaceratorRecipeResult(srcSlot:get_name())
else
result=industrialtest.api.getRotaryMaceratorModifier(srcSlot:get_name(),modifierSlot:get_name())
modified=true
end
return result,modified
end
industrialtest.internal.registerMachine({
name="rotary_macerator",
displayName=S("Rotary Macerator"),
capacity=industrialtest.api.lvPowerFlow*2,
getFormspec=rotaryMacerator.getFormspec,
flow=industrialtest.api.lvPowerFlow,
ioConfig="iiiiii",
requiresWrench=true,
registerActiveVariant=true,
sounds="metal",
powerSlots={"powerStorage"},
storageSlots={"src","modifier","powerStorage","dst","upgrades"},
groups={
_industrialtest_hasPowerInput=1
},
customKeys={
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_macerator_front.png"
},
paramtype2="facedir",
legacy_facedir_simple=true
},
activeCustomKeys={
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_macerator_front_active.png"
}
},
onConstruct=rotaryMacerator.onConstruct,
onTimer=rotaryMacerator.onTimer,
allowMetadataInventoryMove=rotaryMacerator.allowMetadataInventoryMove,
allowMetadataInventoryPut=rotaryMacerator.allowMetadataInventoryPut,
onMetadataInventoryPut=rotaryMacerator.onMetadataInventoryPut,
onMetadataInventoryMove=rotaryMacerator.onMetadataInventoryMove,
onMetadataInventoryTake=rotaryMacerator.onMetadataInventoryTake,
activeOnTimer=rotaryMacerator.activeOnTimer
})
minetest.register_craft({
type="shaped",
output="industrialtest:rotary_macerator",

View File

@ -0,0 +1,220 @@
-- 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 <http://www.gnu.org/licenses/>.
industrialtest.SimpleElectricItemProcessor=table.copy(industrialtest.ActivatedElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.SimpleElectricItemProcessor,{
facedir=true,
sounds="metal",
storageLists={
"src",
"dst",
"powerStorage",
"upgrades"
},
powerLists={
{
list="powerStorage",
direction="i"
}
},
hasPowerInput=true,
ioConfig="iiiiii"
})
function industrialtest.SimpleElectricItemProcessor.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("src",1)
inv:set_size("dst",1)
inv:set_size("powerStorage",1)
inv:set_size("upgrades",4)
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
industrialtest.ActivatedElectricMachine.onConstruct(self,pos)
end
function industrialtest.SimpleElectricItemProcessor.getFormspec(self,pos)
local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local powerPercent=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")*100
local srcPercent=meta:get_float("srcTime")/meta:get_float("maxSrcTime")*100
local formspec={
"list[context;src;3.4,1.8;1,1]",
industrialtest.internal.getItemSlotBg(3.4,1.8,1,1),
(powerPercent>0 and "image[3.4,2.8;1,1;industrialtest_gui_electricity_bg.png^[lowpart:"..powerPercent..":industrialtest_gui_electricity_fg.png]"
or "image[3.4,2.8;1,1;industrialtest_gui_electricity_bg.png]"),
"list[context;powerStorage;3.4,3.9;1,1]",
industrialtest.internal.getItemSlotBg(3.4,3.9,1,1),
(srcPercent>0 and "image[4.9,2.8;1,1;gui_furnace_arrow_bg.png^[lowpart:"..srcPercent..":gui_furnace_arrow_fg.png^[transformR270]"
or "image[4.9,2.8;1,1;gui_furnace_arrow_bg.png^[transformR270]"),
"list[context;dst;6.4,2.8;1,1]",
industrialtest.internal.getItemSlotBg(6.4,2.8,1,1),
"list[context;upgrades;9,0.9;1,4]",
industrialtest.internal.getItemSlotBg(9,0.9,1,4),
"listring[context;src]",
"listring[context;dst]"
}
return parentFormspec..table.concat(formspec,"")
end
function industrialtest.SimpleElectricItemProcessor.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,count)
if toList=="dst" then
return 0
end
return industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,count)
end
function industrialtest.SimpleElectricItemProcessor.allowMetadataInventoryPut(self,pos,listname,index,stack)
if listname=="dst" then
return 0
elseif listname=="src" then
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
if srcSlot:get_name()~=stack:get_name() then
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
end
end
return industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack)
end
function industrialtest.SimpleElectricItemProcessor.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
industrialtest.ActivatedElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
if fromList=="src" and srcSlot:is_empty() then
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
self:updateFormspec(pos)
elseif fromList=="dst" and dstSlot:get_free_space()>0 then
self:triggerIfNeeded(pos)
end
end
function industrialtest.SimpleElectricItemProcessor.onMetadataInventoryPut(self,pos,listname,index,stack)
industrialtest.ActivatedElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack)
self:triggerIfNeeded(pos)
end
function industrialtest.SimpleElectricItemProcessor.onMetadataInventoryTake(self,pos,listname,index,stack)
industrialtest.ActivatedElectricMachine.onMetadataInventoryTake(self,pos,listname,index,stack)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local srcSlot=inv:get_stack("src",1)
local dstSlot=inv:get_stack("dst",1)
if listname=="src" and srcSlot:is_empty() then
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
self:updateFormspec(pos)
elseif listname=="dst" and dstSlot:get_free_space()>0 then
self:triggerIfNeeded(pos)
end
end
function industrialtest.SimpleElectricItemProcessor.register(self)
industrialtest.ActivatedElectricMachine.register(self)
industrialtest.api.addTag(self.name,"simpleElectricItemProcessor")
end
function industrialtest.SimpleElectricItemProcessor.shouldActivate(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
if meta:get_float("maxSrcTime")>0 and meta:get_float("srcTime")>=0 then
return false
end
-- TODO: Take elapsed time into account
local requiredPower=self.opPower*industrialtest.api.getMachineSpeed(meta)
if meta:get_int("industrialtest.powerAmount")<requiredPower then
return false
end
local srcSlot=inv:get_stack("src",1)
if srcSlot:get_count()>0 then
local output=self:getCraftResult(srcSlot)
return output and output.time>0 and inv:room_for_item("dst",output.item)
end
return false
end
function industrialtest.SimpleElectricItemProcessor.shouldDeactivate(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
-- TODO: Take elapsed time into account
local requiredPower=self.opPower*industrialtest.api.getMachineSpeed(meta)
if meta:get_int("industrialtest.powerAmount")<requiredPower then
return true
end
local srcSlot=inv:get_stack("src",1)
if srcSlot:is_empty() then
return true
end
local output=self:getCraftResult(srcSlot)
return not output or output.time==0 or not inv:room_for_item("dst",output.item)
end
function industrialtest.SimpleElectricItemProcessor.activeUpdate(self,pos,elapsed,meta,inv)
local srcSlot=inv:get_stack("src",1)
local srcTime=0
local maxSrcTime
if meta:get_float("maxSrcTime")<=0 then
local output=self:getCraftResult(srcSlot)
maxSrcTime=output.time*self.efficiency
meta:set_float("srcTime",0)
meta:set_float("maxSrcTime",maxSrcTime)
shouldUpdateFormspec=true
else
srcTime=meta:get_float("srcTime")
maxSrcTime=meta:get_float("maxSrcTime")
end
local speed=industrialtest.api.getMachineSpeed(meta)
local requiredPower=elapsed*self.opPower*speed
industrialtest.api.addPower(meta,-requiredPower)
srcTime=srcTime+elapsed
meta:set_int("srcTime",srcTime)
if srcTime>=maxSrcTime then
local output=self:getCraftResult(srcSlot)
local usedItems=srcSlot:get_count()-output.src:get_count()
local multiplier=1
if srcSlot:get_count()>=speed*usedItems then
multiplier=speed
end
if output.item:get_count()>0 then
output.item:set_count(output.item:get_count()*multiplier)
inv:add_item("dst",output.item)
end
meta:set_float("srcTime",-1)
meta:set_float("maxSrcTime",0)
srcSlot:set_count(srcSlot:get_count()-multiplier*usedItems)
inv:set_stack("src",1,srcSlot)
end
return true
end
function industrialtest.SimpleElectricItemProcessor.getCraftResult(self,itemstack)
-- Dummy method
end

View File

@ -15,9 +15,36 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local solarPanel={}
industrialtest.SolarPanelBase=table.copy(industrialtest.ElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.SolarPanelBase,{
sounds="metal",
requiresWrench=true,
storageLists={
"charged"
},
powerLists={
{
list="charged",
direction="o"
}
},
hasPowerOutput=true,
ioConfig="oooooo",
multiplier=1
})
solarPanel.getFormspec=function(pos)
local solarPanels={}
function industrialtest.SolarPanelBase.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("charged",1)
meta:set_float("prevAmount",0)
industrialtest.ElectricMachine.onConstruct(self,pos)
end
function industrialtest.SolarPanelBase.getFormspec(self,pos)
local parentFormspec=industrialtest.ElectricMachine.getFormspec(self,pos)
local amount=minetest.get_natural_light(vector.offset(pos,0,1,0))/15.0
local charging=amount>0.5
local formspec={
@ -27,71 +54,48 @@ solarPanel.getFormspec=function(pos)
or "image[4.7,2.8;1,1;industrialtest_gui_sun_bg.png]"),
"listring[context;charged]"
}
return table.concat(formspec,"")
return parentFormspec..table.concat(formspec,"")
end
solarPanel.onConstruct=function(pos,meta,inv)
inv:set_size("charged",1)
meta:set_float("prevAmount",0)
function industrialtest.SolarPanelBase.register(self)
industrialtest.ElectricMachine.register(self)
table.insert(solarPanels,self.name)
end
solarPanel.onTimer=function(pos,elapsed,meta,inv,config)
local chargedSlot=inv:get_stack("charged",1)
local shouldUpdateFormspec=false
function industrialtest.SolarPanelBase.action(self,pos)
local meta=minetest.get_meta(pos)
local amount=minetest.get_natural_light(vector.offset(pos,0,1,0))/15.0
local charging=amount>0.5
if charging then
industrialtest.api.addPower(meta,math.ceil(amount*config.flow*elapsed))
if industrialtest.api.addPower(meta,math.ceil(amount*self.flow*self.multiplier))>0 then
self:updateFormspec(pos)
end
if meta:get_int("industrialtest.powerAmount")>0 then
if chargedSlot:get_count()>0 and not industrialtest.api.isFullyCharged(chargedSlot:get_meta()) then
industrialtest.api.transferPowerToItem(meta,chargedSlot,math.ceil(config.flow*elapsed))
inv:set_stack("charged",1,chargedSlot)
end
industrialtest.api.powerFlow(pos)
self:trigger(pos)
end
if amount~=meta:get_float("prevAmount") then
shouldUpdateFormspec=true
self:updateFormspec(pos)
meta:set_float("prevAmount",amount)
end
return true,shouldUpdateFormspec
end
local function registerSolarPanelGenerator(config)
industrialtest.internal.registerMachine({
name=config.name,
displayName=config.displayName,
getFormspec=solarPanel.getFormspec,
capacity=config.capacity,
flow=config.flow,
ioConfig="oooooo",
requiresWrench=true,
registerActiveVariant=false,
powerSlots={"charged"},
storageSlots={"charged"},
sounds="metal",
groups={
_industrialtest_hasPowerOutput=1
},
customKeys={
industrialtest.SolarPanel=table.copy(industrialtest.SolarPanelBase)
industrialtest.internal.unpackTableInto(industrialtest.SolarPanel,{
name="industrialtest:solar_panel",
description=S("Solar Panel"),
tiles={
"industrialtest_machine_block.png^industrialtest_"..config.name.."_top.png",
"industrialtest_machine_block.png^industrialtest_solar_panel_top.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png"
}
},
onConstruct=solarPanel.onConstruct,
onTimer=function(pos,elapsed,meta,inv)
return solarPanel.onTimer(pos,elapsed,meta,inv,config)
end
})
end
registerSolarPanelGenerator({
name="solar_panel",
displayName=S("Solar Panel"),
capacity=industrialtest.api.lvPowerFlow*2,
flow=industrialtest.api.lvPowerFlow
})
industrialtest.SolarPanel:register()
minetest.register_craft({
type="shaped",
output="industrialtest:solar_panel",
@ -102,12 +106,25 @@ minetest.register_craft({
}
})
registerSolarPanelGenerator({
name="lv_solar_array",
displayName=S("LV Solar Array"),
industrialtest.LVSolarArray=table.copy(industrialtest.SolarPanelBase)
industrialtest.internal.unpackTableInto(industrialtest.LVSolarArray,{
name="industrialtest:lv_solar_array",
description=S("LV Solar Array"),
tiles={
"industrialtest_machine_block.png^industrialtest_lv_solar_array_top.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png"
},
capacity=industrialtest.api.lvPowerFlow*4,
flow=industrialtest.api.lvPowerFlow*2
flow=industrialtest.api.lvPowerFlow,
multiplier=1.5
})
industrialtest.LVSolarArray:register()
minetest.register_craft({
type="shaped",
output="industrialtest:lv_solar_array",
@ -118,12 +135,24 @@ minetest.register_craft({
}
})
registerSolarPanelGenerator({
name="mv_solar_array",
displayName=S("MV Solar Array"),
industrialtest.MVSolarArray=table.copy(industrialtest.SolarPanelBase)
industrialtest.internal.unpackTableInto(industrialtest.MVSolarArray,{
name="industrialtest:mv_solar_array",
description=S("MV Solar Array"),
tiles={
"industrialtest_machine_block.png^industrialtest_mv_solar_array_top.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png"
},
capacity=industrialtest.api.mvPowerFlow*2,
flow=industrialtest.api.mvPowerFlow
})
industrialtest.MVSolarArray:register()
minetest.register_craft({
type="shaped",
output="industrialtest:mv_solar_array",
@ -134,12 +163,25 @@ minetest.register_craft({
}
})
registerSolarPanelGenerator({
name="hv_solar_array",
displayName=S("HV Solar Array"),
industrialtest.HVSolarArray=table.copy(industrialtest.SolarPanelBase)
industrialtest.internal.unpackTableInto(industrialtest.HVSolarArray,{
name="industrialtest:hv_solar_array",
description=S("HV Solar Array"),
tiles={
"industrialtest_machine_block.png^industrialtest_hv_solar_array_top.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png"
},
capacity=industrialtest.api.hvPowerFlow*2,
flow=industrialtest.api.hvPowerFlow
})
industrialtest.HVSolarArray:register()
minetest.register_craft({
type="shaped",
output="industrialtest:hv_solar_array",
@ -149,3 +191,14 @@ minetest.register_craft({
{"industrialtest:mv_solar_array","industrialtest:mv_solar_array","industrialtest:mv_solar_array"}
}
})
minetest.register_abm({
name="Solar panel updating",
nodenames=solarPanels,
interval=industrialtest.config.updateDelay,
chance=1,
action=function(pos,node)
local def=minetest.registered_nodes[node.name]
def._industrialtest_self:action(pos)
end
})

View File

@ -15,9 +15,61 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local toolWorkshop={}
industrialtest.ToolWorkshop=table.copy(industrialtest.ActivatedElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.ToolWorkshop,{
name="industrialtest:tool_workshop",
description=S("Tool Workshop"),
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_tool_workshop_front.png",
},
sounds="metal",
requiresWrench=true,
facedir=true,
storageLists={
"src",
"upgrades",
"powerStorage"
},
powerLists={
{
list="powerStorage",
direction="i"
}
},
active={
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_tool_workshop_front_active.png",
}
},
capacity=15000,
flow=industrialtest.api.hvPowerFlow,
hasPowerInput=true,
ioConfig="iiiiii",
_opPower=10000,
_efficiency=200
})
toolWorkshop.getFormspec=function(pos)
function industrialtest.ToolWorkshop.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("powerStorage",1)
inv:set_size("src",1)
inv:set_size("upgrades",4)
industrialtest.ActivatedElectricMachine.onConstruct(self,pos)
end
function industrialtest.ToolWorkshop.getFormspec(self,pos)
local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local powerPercent=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")*100
local formspec={
@ -31,79 +83,69 @@ toolWorkshop.getFormspec=function(pos)
industrialtest.internal.getItemSlotBg(9,0.9,1,4),
"listring[context;src]"
}
return table.concat(formspec,"")
return parentFormspec..table.concat(formspec,"")
end
toolWorkshop.onConstruct=function(pos,meta,inv)
inv:set_size("powerStorage",1)
inv:set_size("src",1)
inv:set_size("upgrades",4)
function industrialtest.ToolWorkshop.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
if toList=="src" then
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local movedItemStack=inv:get_stack(fromList,fromIndex)
if not self.isTool(movedItemStack) then
return 0
end
end
return industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
toolWorkshop.onTimer=function(pos,elapsed,meta,inv)
local powerStorageSlot=inv:get_stack("powerStorage",1)
function industrialtest.ToolWorkshop.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
if listname=="tool" and not self.isTool(stack) then
return 0
end
return industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
end
function industrialtest.ToolWorkshop.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
self:triggerIfNeeded(pos)
industrialtest.ActivatedElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
function industrialtest.ToolWorkshop.onMetadataInventoryPut(self,pos,listname,index,stack)
self:triggerIfNeeded(pos)
industrialtest.ActivatedElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack)
end
function industrialtest.ToolWorkshop.shouldActivate(self,pos)
local meta=minetest.get_meta(pos)
local requiredPower=industrialtest.api.getMachineSpeed(meta)*self._opPower
if meta:get_int("industrialtest.powerAmount")<requiredPower then
return false
end
local inv=meta:get_inventory()
local toolSlot=inv:get_stack("src",1)
local requiredPower=industrialtest.api.getMachineSpeed(meta)*10000
local shouldRerunTimer=false
local shouldUpdateFormspec=false
if powerStorageSlot:get_count()>0 then
local stackMeta=powerStorageSlot:get_meta()
if industrialtest.api.transferPower(stackMeta,meta,stackMeta:get_int("industrialtest.powerFlow"))>0 then
shouldUpdateFormspec=true
shouldRerunTimer=true
industrialtest.api.updateItemPowerText(powerStorageSlot)
inv:set_stack("powerStorage",1,powerStorageSlot)
end
return not toolSlot:is_empty() and self.isTool(toolSlot) and toolSlot:get_wear()>0
end
if toolSlot:get_count()>0 and toolSlot:get_wear()>0 and meta:get_int("industrialtest.powerAmount")>=requiredPower then
minetest.swap_node(pos,{
name="industrialtest:tool_workshop_active",
param2=minetest.get_node(pos).param2
})
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
function industrialtest.ToolWorkshop.shouldDeactivate(self,pos)
return not self:shouldActivate(pos)
end
return shouldRerunTimer,shouldUpdateFormspec
end
toolWorkshop.activeOnTimer=function(pos,elapsed,meta,inv)
local powerStorageSlot=inv:get_stack("powerStorage",1)
function industrialtest.ToolWorkshop.activeUpdate(self,pos,elapsed,meta,inv)
local toolSlot=inv:get_stack("src",1)
local speed=industrialtest.api.getMachineSpeed(meta)
local requiredPower=speed*10000
local shouldRerunTimer=false
local shouldUpdateFormspec=false
if powerStorageSlot:get_count()>0 then
local stackMeta=powerStorageSlot:get_meta()
if industrialtest.api.transferPower(stackMeta,meta,stackMeta:get_int("industrialtest.powerFlow"))>0 then
shouldUpdateFormspec=true
shouldRerunTimer=true
industrialtest.api.updateItemPowerText(powerStorageSlot)
inv:set_stack("powerStorage",1,powerStorageSlot)
end
end
if toolSlot:get_count()>0 and toolSlot:get_wear()>0 and meta:get_int("industrialtest.powerAmount")>=requiredPower then
local removed=math.min(toolSlot:get_wear(),speed*200)
local requiredPower=industrialtest.api.getMachineSpeed(meta)*self._opPower
local removed=math.min(toolSlot:get_wear(),speed*self._efficiency)
toolSlot:set_wear(toolSlot:get_wear()-removed)
inv:set_stack("src",1,toolSlot)
industrialtest.api.addPower(meta,-requiredPower)
shouldRerunTimer=true
shouldUpdateFormspec=true
else
minetest.swap_node(pos,{
name="industrialtest:tool_workshop",
param2=minetest.get_node(pos).param2
})
return true
end
return shouldRerunTimer,shouldUpdateFormspec
end
local function isTool(stack)
function industrialtest.ToolWorkshop.isTool(stack)
local def=minetest.registered_tools[stack:get_name()]
if not def or industrialtest.api.hasPowerStorage(stack:get_meta())then
return false
@ -111,76 +153,8 @@ local function isTool(stack)
return def.groups and (def.groups.pickaxe or def.groups.sword or def.groups.hoe or def.groups.tool or def.groups.weapon or def.groups.shovel or def.groups.axe)
end
toolWorkshop.allowMetadataInventoryMove=function(pos,fromList,fromIndex,toList,toIndex,count)
if toList=="src" then
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
local movedItemStack=inv:get_stack(fromList,fromIndex)
if not isTool(movedItemStack) then
return 0
end
end
return count
end
industrialtest.ToolWorkshop:register()
toolWorkshop.allowMetadataInventoryPut=function(pos,listname,index,stack)
if listname=="tool" and not isTool(stack) then
return 0
end
return stack:get_count()
end
toolWorkshop.metadataChange=function(pos)
minetest.get_node_timer(pos):start(industrialtest.updateDelay)
end
industrialtest.internal.registerMachine({
name="tool_workshop",
displayName=S("Tool Workshop"),
getFormspec=toolWorkshop.getFormspec,
capacity=20000,
flow=industrialtest.api.hvPowerFlow,
ioConfig="iiiiii",
requiresWrench=true,
registerActiveVariant=true,
powerSlots={"powerStorage"},
storageSlots={"src"},
sounds="metal",
groups={
_industrialtest_hasPowerInput=1
},
customKeys={
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_tool_workshop_front.png",
"industrialtest_advanced_machine_block.png"
},
paramtype2="facedir",
legacy_facedir_simple=true
},
activeCustomKeys={
tiles={
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png",
"industrialtest_advanced_machine_block.png^industrialtest_tool_workshop_front_active.png",
"industrialtest_advanced_machine_block.png"
},
},
onConstruct=toolWorkshop.onConstruct,
onTimer=toolWorkshop.onTimer,
activeOnTimer=toolWorkshop.activeOnTimer,
allowMetadataInventoryMove=toolWorkshop.allowMetadataInventoryMove,
allowMetadataInventoryPut=toolWorkshop.allowMetadataInventoryPut,
onMetadataInventoryPut=toolWorkshop.metadataChange,
onMetadataInventoryMove=toolWorkshop.metadataChange
})
minetest.register_craft({
type="shaped",
output="industrialtest:tool_workshop",

View File

@ -15,81 +15,70 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local transformer={}
transformer.onPowerFlow=function(pos,side,amount)
local normalized=industrialtest.api.normalizeSide(pos,side)
local def=minetest.registered_nodes[minetest.get_node(pos).name]
if normalized~=5 and amount>=def._industrialtest_lowerFlow then
minetest.remove_node(pos)
industrialtest.internal.explode(pos,2)
end
end
transformer.onTimer=function(pos,elapsed,meta)
local powerAmount=meta:get_int("industrialtest.powerAmount")
local def=minetest.registered_nodes[minetest.get_node(pos).name]
local afterFlowLower=false
local afterFlowUpper=false
if powerAmount>=def._industrialtest_lowerFlow then
afterFlowLower,_=industrialtest.api.powerFlow(pos,{
[1]=true,
[2]=true,
[3]=true,
[4]=true,
[6]=true
},def._industrialtest_lowerFlow)
end
if powerAmount>=def._industrialtest_upperFlow then
afterFlowUpper,_=industrialtest.api.powerFlow(pos,{[5]=true},def._industrialtest_upperFlow)
end
return powerAmount>0 and (afterFlowLower or afterFlowUpper),false
end
local function registerTransformer(config)
industrialtest.internal.registerMachine({
name=config.name,
displayName=config.displayName,
capacity=industrialtest.api.ivPowerFlow,
flow=industrialtest.api.ivPowerFlow,
ioConfig="aaaaaa",
storageSlots={},
powerSlots={},
sounds=config.sounds,
groups={
_industrialtest_hasPowerOutput=1,
_industrialtest_hasPowerInput=1,
},
customKeys={
tiles={
config.machineBlockTexture.."^industrialtest_"..config.name.."_side.png",
config.machineBlockTexture.."^industrialtest_"..config.name.."_side.png",
config.machineBlockTexture.."^industrialtest_"..config.name.."_side.png",
config.machineBlockTexture.."^industrialtest_"..config.name.."_side.png",
config.machineBlockTexture.."^industrialtest_"..config.name.."_side.png",
config.machineBlockTexture.."^industrialtest_"..config.name.."_front.png"
},
paramtype2="facedir",
legacy_facedir_simple=true,
_industrialtest_lowerFlow=config.lowerFlow,
_industrialtest_upperFlow=config.upperFlow,
_industrialtest_onPowerFlow=transformer.onPowerFlow
},
requiresWrench=config.requiresWrench,
industrialtest.Transformer=table.copy(industrialtest.ElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.Transformer,{
withoutFormspec=true,
onTimer=transformer.onTimer
facedir=true,
storageLists={},
powerLists={},
hasPowerInput=true,
hasPowerOutput=true
})
function industrialtest.Transformer.register(self)
self.ioConfig={
{
mode="a",
flow=self.lowerFlow
},
{
mode="a",
flow=self.lowerFlow
},
{
mode="a",
flow=self.lowerFlow
},
{
mode="a",
flow=self.lowerFlow
},
{
mode="a",
flow=self.flow
},
{
mode="a",
flow=self.lowerFlow
}
}
industrialtest.ElectricMachine.register(self)
end
registerTransformer({
name="lv_transformer",
displayName=S("LV Transformer"),
machineBlockTexture="industrialtest_wood_machine_block.png",
requiresWrench=false,
lowerFlow=industrialtest.api.lvPowerFlow,
upperFlow=industrialtest.api.mvPowerFlow,
sounds="wood"
function industrialtest.Transformer.onPowerFlow(self,pos)
self:trigger(pos)
end
industrialtest.LVTransformer=table.copy(industrialtest.Transformer)
industrialtest.internal.unpackTableInto(industrialtest.LVTransformer,{
name="industrialtest:lv_transformer",
description=S("LV Transformer"),
sounds="wood",
tiles={
"industrialtest_wood_machine_block.png^industrialtest_lv_transformer_side.png",
"industrialtest_wood_machine_block.png^industrialtest_lv_transformer_side.png",
"industrialtest_wood_machine_block.png^industrialtest_lv_transformer_side.png",
"industrialtest_wood_machine_block.png^industrialtest_lv_transformer_side.png",
"industrialtest_wood_machine_block.png^industrialtest_lv_transformer_side.png",
"industrialtest_wood_machine_block.png^industrialtest_lv_transformer_front.png"
},
capacity=industrialtest.api.mvPowerFlow,
flow=industrialtest.api.mvPowerFlow,
lowerFlow=industrialtest.api.lvPowerFlow
})
industrialtest.LVTransformer:register()
minetest.register_craft({
type="shaped",
output="industrialtest:lv_transformer",
@ -100,15 +89,27 @@ minetest.register_craft({
}
})
registerTransformer({
name="mv_transformer",
displayName=S("MV Transformer"),
machineBlockTexture="industrialtest_machine_block.png",
industrialtest.MVTransformer=table.copy(industrialtest.Transformer)
industrialtest.internal.unpackTableInto(industrialtest.MVTransformer,{
name="industrialtest:mv_transformer",
description=S("MV Transformer"),
sounds="metal",
requiresWrench=true,
lowerFlow=industrialtest.api.mvPowerFlow,
upperFlow=industrialtest.api.hvPowerFlow,
sounds="metal"
tiles={
"industrialtest_machine_block.png^industrialtest_mv_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_mv_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_mv_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_mv_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_mv_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_mv_transformer_front.png"
},
capacity=industrialtest.api.hvPowerFlow,
flow=industrialtest.api.hvPowerFlow,
lowerFlow=industrialtest.api.mvPowerFlow
})
industrialtest.MVTransformer:register()
minetest.register_craft({
type="shaped",
output="industrialtest:mv_transformer",
@ -119,15 +120,27 @@ minetest.register_craft({
}
})
registerTransformer({
name="hv_transformer",
displayName=S("HV Transformer"),
machineBlockTexture="industrialtest_machine_block.png",
industrialtest.HVTransformer=table.copy(industrialtest.Transformer)
industrialtest.internal.unpackTableInto(industrialtest.HVTransformer,{
name="industrialtest:hv_transformer",
description=S("HV Transformer"),
sounds="metal",
requiresWrench=true,
lowerFlow=industrialtest.api.hvPowerFlow,
upperFlow=industrialtest.api.evPowerFlow,
sounds="metal"
tiles={
"industrialtest_machine_block.png^industrialtest_hv_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_hv_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_hv_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_hv_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_hv_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_hv_transformer_front.png"
},
capacity=industrialtest.api.evPowerFlow,
flow=industrialtest.api.evPowerFlow,
lowerFlow=industrialtest.api.hvPowerFlow
})
industrialtest.HVTransformer:register()
minetest.register_craft({
type="shaped",
output="industrialtest:hv_transformer",
@ -138,15 +151,27 @@ minetest.register_craft({
}
})
registerTransformer({
name="ev_transformer",
displayName=S("EV Transformer"),
machineBlockTexture="industrialtest_machine_block.png",
industrialtest.EVTransformer=table.copy(industrialtest.Transformer)
industrialtest.internal.unpackTableInto(industrialtest.EVTransformer,{
name="industrialtest:ev_transformer",
description=S("EV Transformer"),
sounds="metal",
requiresWrench=true,
lowerFlow=industrialtest.api.evPowerFlow,
upperFlow=industrialtest.api.ivPowerFlow,
sounds="metal"
tiles={
"industrialtest_machine_block.png^industrialtest_ev_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_ev_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_ev_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_ev_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_ev_transformer_side.png",
"industrialtest_machine_block.png^industrialtest_ev_transformer_front.png"
},
capacity=industrialtest.api.ivPowerFlow,
flow=industrialtest.api.ivPowerFlow,
lowerFlow=industrialtest.api.evPowerFlow
})
industrialtest.EVTransformer:register()
minetest.register_craft({
type="shaped",
output="industrialtest:ev_transformer",

View File

@ -15,9 +15,46 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local windMill={}
industrialtest.WindMill=table.copy(industrialtest.ElectricMachine)
industrialtest.internal.unpackTableInto(industrialtest.WindMill,{
name="industrialtest:wind_mill",
description=S("Wind Mill"),
tiles={
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png^industrialtest_wind_mill_side.png",
"industrialtest_machine_block.png^industrialtest_wind_mill_side.png",
"industrialtest_machine_block.png^industrialtest_wind_mill_side.png",
"industrialtest_machine_block.png^industrialtest_wind_mill_side.png"
},
sounds="metal",
requiresWrench=true,
storageLists={
"charged"
},
powerLists={
{
list="charged",
direction="o"
}
},
capacity=7000,
flow=industrialtest.api.lvPowerFlow,
hasPowerOutput=true,
ioConfig="oooooo",
})
windMill.getFormspec=function(pos)
function industrialtest.WindMill.onConstruct(self,pos)
local meta=minetest.get_meta(pos)
local inv=meta:get_inventory()
inv:set_size("charged",1)
meta:set_int("prevCharging",0)
meta:set_int("charging",0)
industrialtest.ElectricMachine.onConstruct(self,pos)
end
function industrialtest.WindMill.getFormspec(self,pos)
local parentFormspec=industrialtest.ElectricMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local charging=meta:get_int("charging")
local formspec={
@ -27,18 +64,11 @@ windMill.getFormspec=function(pos)
or "image[4.7,3;1,1;industrialtest_gui_wind_bg.png]"),
"listring[context;charged]"
}
return table.concat(formspec,"")
return parentFormspec..table.concat(formspec,"")
end
windMill.onConstruct=function(pos,meta,inv)
inv:set_size("charged",1)
meta:set_int("prevCharging",0)
meta:set_int("charging",0)
end
windMill.onTimer=function(pos,elapsed,meta,inv)
local chargedSlot=inv:get_stack("charged",1)
local shouldUpdateFormspec=false
function industrialtest.WindMill.action(self,pos)
local meta=minetest.get_meta(pos)
local charging
if industrialtest.mtgAvailable then
charging=math.min(math.max(pos.y,0)/150,1.0)
@ -67,48 +97,17 @@ windMill.onTimer=function(pos,elapsed,meta,inv)
break
end
end
industrialtest.api.addPower(meta,math.ceil(charging*elapsed*industrialtest.api.lvPowerFlow))
if industrialtest.api.addPower(meta,math.ceil(charging*industrialtest.api.lvPowerFlow))>0 then
self:trigger(pos)
end
if meta:get_int("prevCharging")~=charging then
shouldUpdateFormspec=true
meta:set_int("prevCharging",charging)
self:updateFormspec(pos)
end
if chargedSlot:get_count()>0 and meta:get_int("industrialtest.powerAmount")>0 then
if industrialtest.api.transferPowerToItem(meta,chargedSlot,industrialtest.api.lvPowerFlow)>0 then
inv:set_stack("charged",1,chargedSlot)
end
end
industrialtest.api.powerFlow(pos)
meta:set_int("charging",charging*100)
return true,shouldUpdateFormspec
end
industrialtest.internal.registerMachine({
name="wind_mill",
displayName=S("Wind Mill"),
getFormspec=windMill.getFormspec,
capacity=7000,
flow=industrialtest.api.lvPowerFlow,
ioConfig="oooooo",
requiresWrench=true,
registerActiveVariant=false,
powerSlots={"charged"},
storageSlots={"charged"},
sounds="metal",
groups={
_industrialtest_hasPowerOutput=1
},
customKeys={
tiles={
"industrialtest_machine_block.png",
"industrialtest_machine_block.png",
"industrialtest_machine_block.png^industrialtest_wind_mill_side.png",
"industrialtest_machine_block.png^industrialtest_wind_mill_side.png",
"industrialtest_machine_block.png^industrialtest_wind_mill_side.png",
"industrialtest_machine_block.png^industrialtest_wind_mill_side.png"
}
},
onConstruct=windMill.onConstruct,
onTimer=windMill.onTimer
})
industrialtest.WindMill:register()
minetest.register_craft({
type="shaped",
@ -119,3 +118,13 @@ minetest.register_craft({
{"","industrialtest:refined_iron_ingot",""}
}
})
minetest.register_abm({
name="Wind mill updating",
nodenames={"industrialtest:wind_mill"},
interval=industrialtest.config.updateDelay,
chance=1,
action=function(pos)
industrialtest.WindMill:action(pos)
end
})

View File

@ -1,5 +1,5 @@
name=industrialtest
description=Adds various machinery
optional_depends=default,bucket,3d_armor,mcl_core,mcl_copper,mcl_armor,mcl_deepslate,mcl_nether,mcl_buckets,mcl_util,mcl_dye,mcl_rubber,pipeworks,mesecons
optional_depends=default,bucket,3d_armor,mcl_core,mcl_copper,mcl_armor,mcl_deepslate,mcl_nether,mcl_buckets,mcl_util,mcl_dye,mcl_rubber,pipeworks,logistica,mesecons
author=IndustrialTest Team
title=IndustrialTest

View File

@ -354,6 +354,19 @@ if not industrialtest.mods.mclRubber then
name=="mcl_core:podzol" or name=="mcl_core:podzol_snow" or
name=="mcl_core:dirt" or name=="mcl_core:mycelium" or name=="mcl_core:coarse_dirt"
end)
definition._on_bone_meal=function(itemstack,user,pointed)
if industrialtest.random:next(1,100)>45 then
return
end
local meta=minetest.get_meta(pointed.under)
local stage=meta:get_int("stage") or 0
stage=stage+1
if stage>=3 then
industrialtest.internal.makeRubberTree(pointed.under)
else
meta:set_int("stage",stage)
end
end
minetest.register_abm({
label="Rubber sapling growing",
nodenames={"industrialtest:rubber_sapling"},
@ -379,23 +392,6 @@ if not industrialtest.mods.mclRubber then
end
end
})
mcl_dye.register_on_bone_meal_apply(function(pointed)
local node=minetest.get_node(pointed.under)
if node.name~="industrialtest:rubber_sapling" then
return
end
if industrialtest.random:next(1,100)>45 then
return
end
local meta=minetest.get_meta(pointed.under)
local stage=meta:get_int("stage") or 0
stage=stage+1
if stage>=3 then
industrialtest.internal.makeRubberTree(pointed.under)
else
meta:set_int("stage",stage)
end
end)
end
definition.groups.attached_node=1
definition.groups.dig_immediate=3

8
settingtypes.txt Normal file
View File

@ -0,0 +1,8 @@
# This determines value how frequently machines update
industrialtest.updateDelay (Update delay) float 1.0
# Whether electrocution by uninsulated cables is used
industrialtest.electrocution (Electrocution) bool true
# Enables additional utils useful when developing mod
industrialtest.developerMode (Developer mode) bool false

Binary file not shown.

View File

@ -3,4 +3,4 @@
- `industrialtest_gui_water.png` was taken from Minetest Game (by Cisoun licensed with CC BY-SA 3.0)
- `industrialtest_gui_river_water.png` was taken from Minetest Game (by paramat licensed with CC BY-SA 3.0)
... rest was made either by LuanHawk, mrkubax10 or Migdyn and is licensed with CC BY 4.0 International
... rest was made either by LuanHawk, mrkubax10, HandfulOfFrogs or Migdyn and is licensed with CC BY 4.0 International

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 302 B

View File

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

Before

Width:  |  Height:  |  Size: 686 B

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -0,0 +1,160 @@
-- 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 <http://www.gnu.org/licenses/>.
industrialtest.ActivatedElectricTool=table.copy(industrialtest.ElectricTool)
function industrialtest.ActivatedElectricTool.createDefinitionTable(self)
local def=industrialtest.ElectricTool.createDefinitionTable(self)
def.groups._industrialtest_activatedElectricTool=1
def.tool_capabilities.full_punch_interval=self.fullPunchInterval
if self.digs then
self:defineToolCapabilities(def,nil,self.digSpeed)
end
if self.hits then
def.tool_capabilities.damage_groups={}
for _,hitType in ipairs(self.hits) do
def.tool_capabilities.damage_groups[hitType]=1
end
end
return def
end
function industrialtest.ActivatedElectricTool.createActiveDefinitionTable(self)
local def=self:createDefinitionTable()
if self.digs or self.hits then
self:defineToolCapabilities(def,self.active.times,self.active.digSpeed)
end
def.groups.not_in_creative_inventory=1
def.after_use=function(itemstack,user,node,digparams)
if self:afterUse(itemstack,user,node,digparams) then
return itemstack
end
return nil
end
return def
end
function industrialtest.ActivatedElectricTool.register(self)
industrialtest.ElectricTool.register(self)
local def=self:createActiveDefinitionTable()
minetest.register_tool(self.name.."_active",def)
end
function industrialtest.ActivatedElectricTool.beforeUse(self,itemstack,node)
local def=itemstack:get_definition()
if self:canActivate(itemstack,node) then
if not self.isActive(itemstack) then
itemstack:set_name(itemstack:get_name().."_active")
end
return true
else
itemstack:set_name(self.name)
end
return false
end
function industrialtest.ActivatedElectricTool.afterUse(self,itemstack,user,node,digparams)
local meta=itemstack:get_meta()
industrialtest.api.addPowerToItem(itemstack,-self:getOpPower(itemstack))
return true
end
function industrialtest.ActivatedElectricTool.canActivate(self,itemstack,node)
local meta=itemstack:get_meta()
return meta:get_int("industrialtest.powerAmount")>=self:getOpPower(itemstack)
end
function industrialtest.ActivatedElectricTool.isActive(itemstack)
return string.sub(itemstack:get_name(),-string.len("_active"),-1)=="_active"
end
function industrialtest.ActivatedElectricTool.defineToolCapabilities(self,def,times,digSpeed)
if industrialtest.mtgAvailable then
if self.digs then
def.tool_capabilities.groupcaps={}
for _,digType in ipairs(self.digs) do
def.tool_capabilities.groupcaps[digType]={
times=times,
maxlevel=self.digLevel+1
}
if digType=="choppy" then
def.groups.axe=1
elseif digType=="cracky" then
def.groups.pickaxe=1
elseif digType=="crumbly" then
def.groups.shovel=1
elseif digType=="hoey" then
def.groups.hoe=1
end
end
end
if self.hits then
for _,hitType in ipairs(self.hits) do
if hitType=="fleshy" then
def.groups.sword=1
end
end
end
elseif industrialtest.mclAvailable then
if self.digs then
local digTypeMapping={
choppy={"axey"},
cracky={"pickaxey"},
crumbly={"shovely"},
hoey={"hoey"},
snappy={"swordy","swordy_cobweb"}
}
def.groups.dig_speed_class=self.digSpeedClass
def._mcl_diggroups={}
for _,digType in ipairs(self.digs) do
for _,mappedDigType in ipairs(digTypeMapping[digType]) do
def._mcl_diggroups[mappedDigType]={
speed=digSpeed,
level=5-self.digLevel,
uses=-1
}
end
end
end
if self.hits then
for _,hitType in ipairs(self.hits) do
if hitType=="fleshy" then
def.groups.weapon=1
def.groups.sword=1
end
end
end
end
end
minetest.register_on_punchnode(function(pos,node,user)
if not user then
return
end
local itemstack=user:get_wielded_item()
local def=itemstack:get_definition()
if def and def._industrialtest_self and def.groups and def.groups._industrialtest_activatedElectricTool and
def._industrialtest_self:beforeUse(itemstack,node) then
user:set_wielded_item(itemstack)
end
end)

View File

@ -15,72 +15,44 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.BatPackBase=table.copy(industrialtest.ElectricGearTool)
industrialtest.internal.unpackTableInto(industrialtest.BatPackBase,{
part="torso"
})
local updateDelta=0
local function registerBatpack(config)
if industrialtest.mtgAvailable then
armor:register_armor("industrialtest:"..config.name,{
description=config.displayName,
inventory_image="industrialtest_"..config.name.."_inv.png",
groups={
armor_torso=1,
armor_heal=0,
_industrialtest_batpack=1
},
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=config.powerCapacity,
_industrialtest_powerFlow=config.powerFlow
})
elseif industrialtest.mclAvailable then
minetest.register_tool("industrialtest:"..config.name,{
description=config.displayName,
inventory_image="industrialtest_"..config.name.."_inv.png",
groups={
armor=1,
non_combat_armor=1,
armor_torso=1,
non_combat_torso=1,
_industrialtest_batpack=1
},
sounds={
_mcl_armor_equip="mcl_armor_equip_iron",
_mcl_armor_unequip="mcl_armor_unequip_iron"
},
on_place=mcl_armor.equip_on_use,
on_secondary_use=mcl_armor.equip_on_use,
_mcl_armor_element="torso",
_mcl_armor_texture="industrialtest_"..config.name..".png",
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=config.powerCapacity,
_industrialtest_powerFlow=config.powerFlow
})
end
end
local function onGlobalStep(player,inv,stack,index,def)
if not def.groups or not def.groups._industrialtest_batpack then
function industrialtest.BatPackBase.update(self,player,inv,itemstack,dtime)
updateDelta=updateDelta+dtime
if updateDelta<industrialtest.config.updateDelay then
return false
end
updateDelta=0
local wielded=player:get_wielded_item()
local wieldedMeta=wielded:get_meta()
if not industrialtest.api.hasPowerStorage(wieldedMeta) or wieldedMeta:get_int("industrialtest.powerFlow")>def._industrialtest_powerFlow then
return true
if not industrialtest.api.hasPowerStorage(wieldedMeta) or wieldedMeta:get_int("industrialtest.powerFlow")>self.flow then
return false
end
if industrialtest.api.transferPowerFromItem(stack,wieldedMeta,def._industrialtest_powerFlow)>0 then
if industrialtest.api.transferPowerFromItem(itemstack,wieldedMeta,self.flow)>0 then
industrialtest.api.updateItemPowerText(wielded)
player:set_wielded_item(wielded)
inv:set_stack("armor",index,stack)
end
return true
end
return false
end
registerBatpack({
name="batpack_v",
displayName=S("BatPack"),
powerCapacity=60000,
powerFlow=industrialtest.api.lvPowerFlow
industrialtest.BatPack=table.copy(industrialtest.BatPackBase)
industrialtest.internal.unpackTableInto(industrialtest.BatPack,{
name="industrialtest:batpack_v",
description=S("BatPack"),
inventoryImage="industrialtest_batpack_v_inv.png",
modelImage="industrialtest_batpack_v.png",
capacity=60000,
flow=industrialtest.api.lvPowerFlow
})
industrialtest.BatPack:register()
minetest.register_craft({
type="shaped",
output="industrialtest:batpack_v",
@ -91,12 +63,18 @@ minetest.register_craft({
}
})
registerBatpack({
name="lappack_v",
displayName=S("LapPack"),
powerCapacity=300000,
powerFlow=industrialtest.api.hvPowerFlow
industrialtest.LapPack=table.copy(industrialtest.BatPackBase)
industrialtest.internal.unpackTableInto(industrialtest.LapPack,{
name="industrialtest:lappack_v",
description=S("LapPack"),
inventoryImage="industrialtest_lappack_v_inv.png",
modelImage="industrialtest_lappack_v.png",
capacity=60000,
flow=industrialtest.api.lvPowerFlow
})
industrialtest.LapPack:register()
minetest.register_craft({
type="shaped",
output="industrialtest:lappack_v",
@ -106,33 +84,3 @@ minetest.register_craft({
{industrialtest.elementKeys.powerCarrier,"",industrialtest.elementKeys.powerCarrier}
}
})
minetest.register_globalstep(function(dtime)
updateDelta=updateDelta+dtime
if updateDelta<industrialtest.updateDelay then
return
end
updateDelta=0
local players=minetest.get_connected_players()
for _,player in ipairs(players) do
if industrialtest.mtgAvailable then
local _,inv=armor:get_valid_player(player,"")
if inv then
local armorList=inv:get_list("armor")
assert(armorList)
for i=1,#armorList do
local stack=armorList[i]
local def=stack:get_definition()
if onGlobalStep(player,inv,stack,i,def) then
break
end
end
end
elseif industrialtest.mclAvailable then
local inv=player:get_inventory()
local stack=inv:get_stack("armor",3)
local def=stack:get_definition()
onGlobalStep(player,inv,stack,3,def)
end
end
end)

View File

@ -19,23 +19,6 @@ industrialtest.internal.registeredElectricDrills={}
industrialtest.internal.registeredElectricHoes={}
industrialtest.internal.registeredElectricSabers={}
local function isActive(itemstack)
return string.sub(itemstack:get_name(),-string.len("_active"),-1)=="_active"
end
local function beforeUse(user,itemstack,canDig)
local meta=itemstack:get_meta()
local def=itemstack:get_definition()
if meta:get_int("industrialtest.powerAmount")>=20 and canDig then
if not isActive(itemstack) then
itemstack:set_name(itemstack:get_name().."_active")
end
else
itemstack:set_name(def._industrialtest_inactiveName)
end
user:set_wielded_item(itemstack)
end
minetest.register_on_punchnode(function(pos,node,user,pointed)
if not user then
return

115
tools/electric_armor.lua Normal file
View File

@ -0,0 +1,115 @@
-- 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 <http://www.gnu.org/licenses/>.
industrialtest.ElectricArmor={
prepare=industrialtest.ElectricItem.prepare
}
function industrialtest.ElectricArmor.createDefinitionTableForElement(self,element)
local def={
description=element.description,
inventory_image=element.inventoryImage,
groups={
_industrialtest_electricArmor=1,
["armor_"..element.element]=1
},
_industrialtest_self=self
}
if industrialtest.mclAvailable then
def.groups.armor=1
def.groups.non_combat_armor=1
def.sounds={
_mcl_armor_equip="mcl_armor_equip_iron",
_mcl_armor_unequip="mcl_armor_unequip_iron"
}
def.on_place=mcl_armor.armor_on_use
def.on_secondary_use=mcl_armor.armor_on_use
def._mcl_armor_element=element.element
if type(element.texture)=="string" then
def._mcl_armor_texture=element.texture
else
def._mcl_armor_texture=element.texture[2] or element.texture[1]
end
end
return def
end
function industrialtest.ElectricArmor.register(self)
for _,element in ipairs(self.elements) do
local def=self:createDefinitionTableForElement(element)
local name=self.name.."_"..element.name
if industrialtest.mtgAvailable then
armor:register_armor(name,def)
elseif industrialtest.mclAvailable then
minetest.register_tool(name,def)
end
end
end
function industrialtest.ElectricArmor.tryReduceDamage(self,itemstack,hpChange)
local meta=itemstack:get_meta()
local targetReducedDamage=math.floor(math.abs(hpChange)*self:getReducedDamageForItem(itemstack))
local powerPerDamage=self:getPowerPerDamageForItem(itemstack)
local requiredPower=targetReducedDamage*powerPerDamage
local availablePower=math.min(meta:get_int("industrialtest.powerAmount"),requiredPower)
return math.floor(availablePower/powerPerDamage)
end
function industrialtest.ElectricArmor.getReducedDamageForItem(self,itemstack)
-- dummy function
return 0
end
function industrialtest.ElectricArmor.getPowerPerDamageForItem(self,itemstack)
-- dummy function
return 0
end
minetest.register_on_player_hpchange(function(player,hpChange)
if hpChange>0 or not player:is_player() then
return hpChange
end
local inv
if industrialtest.mtgAvailable then
_,inv=armor:get_valid_player(player,"")
if not inv then
return hpChange
end
elseif industrialtest.mclAvailable then
inv=player:get_inventory()
end
local armorList=inv:get_list("armor")
assert(armorList)
local result=hpChange
for i=1,#armorList do
local itemstack=armorList[i]
local def=itemstack:get_definition()
if def.groups and def.groups._industrialtest_electricArmor and def._industrialtest_self then
local reducedDamage=def._industrialtest_self:tryReduceDamage(itemstack,hpChange)
if reducedDamage>0 then
result=result+reducedDamage
industrialtest.api.addPowerToItem(itemstack,-reducedDamage*def._industrialtest_self:getPowerPerDamageForItem(itemstack))
inv:set_stack("armor",i,itemstack)
end
end
end
return result
end,true)

View File

@ -15,107 +15,42 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.ElectricChainsawBase=table.copy(industrialtest.ActivatedElectricTool)
industrialtest.internal.unpackTableInto(industrialtest.ElectricChainsawBase,{
digs={"choppy"}
})
local electricChainsaw={}
electricChainsaw.afterUse=function(itemstack,config)
local meta=itemstack:get_meta()
industrialtest.api.addPowerToItem(itemstack,-20)
if meta:get_int("industrialtest.powerAmount")<20 then
itemstack:set_name("industrialtest:"..config.name)
function industrialtest.ElectricChainsawBase.use(self,itemstack,user,pointed)
if not industrialtest.mclAvailable then
return false
end
return itemstack
end
local function registerElectricChainsaw(config)
local definition={
description=config.displayName,
inventory_image="industrialtest_"..config.name..".png",
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=10000,
_industrialtest_powerFlow=industrialtest.api.lvPowerFlow,
_industrialtest_inactiveName="industrialtest:"..config.name
}
if industrialtest.mtgAvailable then
definition.tool_capabilities={
full_punch_interval=0.5,
max_drop_level=config.maxDropLevel,
groupcaps={
choppy={
times=config.inactiveTimes,
maxlevel=config.maxLevel
}
}
}
definition.groups={
axe=1
}
elseif industrialtest.mclAvailable then
definition.tool_capabilities={
full_punch_interval=0.5,
max_drop_level=config.maxDropLevel,
}
definition.groups={
tool=1,
dig_speed_class=config.digSpeedClass,
}
definition.on_place=function(itemstack,user,pointed)
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.powerAmount")>=20 then
local itemstackCopy=itemstack
if itemstack:get_wear()~=industrialtest.internal.mclMakeStrippedTrunk(itemstackCopy,user,pointed,true):get_wear() then
industrialtest.api.addPowerToItem(itemstack,-20)
return itemstack
return itemstack:get_wear()~=industrialtest.internal.mclMakeStrippedTrunk(itemstackCopy,user,pointed,true):get_wear()
end
function industrialtest.ElectricChainsawBase.getOpPower(self,itemstack)
return 50
end
return nil
end
definition.after_use=function(itemstack)
-- Hack to make sure that chainsaw won't be destroyed when has 0 EU in MCL
return nil
end
definition._mcl_diggroups={
axey={
speed=config.inactiveDigSpeed,
level=config.digLevel,
uses=-1
industrialtest.ElectricChainsaw=table.copy(industrialtest.ElectricChainsawBase)
industrialtest.internal.unpackTableInto(industrialtest.ElectricChainsaw,{
name="industrialtest:electric_chainsaw",
description=S("Electric Chainsaw"),
inventoryImage="industrialtest_electric_chainsaw.png",
capacity=10000,
flow=industrialtest.api.lvPowerFlow,
digLevel=0,
digSpeedClass=4,
digSpeed=1,
active={
times={[1]=1.7,[2]=1.2,[3]=1.0,[4]=0.7},
digSpeed=7
}
}
definition._mcl_toollike_wield=true
end
minetest.register_tool("industrialtest:"..config.name,definition)
definition=table.copy(definition)
if industrialtest.mtgAvailable then
definition.tool_capabilities.groupcaps.choppy.times=config.activeTimes
elseif industrialtest.mclAvailable then
definition._mcl_diggroups.axey.speed=config.activeDigSpeed
end
definition.groups.not_in_creative_inventory=1
definition.on_use=nil
definition.after_use=function(itemstack)
return electricChainsaw.afterUse(itemstack,config)
end
minetest.register_tool("industrialtest:"..config.name.."_active",definition)
industrialtest.internal.registeredElectricChainsaws["industrialtest:"..config.name]=true
industrialtest.internal.registeredElectricChainsaws["industrialtest:"..config.name.."_active"]=true
end
local definition={
name="electric_chainsaw",
displayName=S("Electric Chainsaw")
}
if industrialtest.mtgAvailable then
definition.maxDropLevel=1
definition.inactiveTimes={[1]=10,[2]=5.6,[3]=4}
definition.maxLevel=2
definition.activeTimes={[1]=2.2,[2]=1.1,[3]=0.7}
elseif industrialtest.mclAvailable then
definition.digSpeedClass=4
definition.maxDropLevel=4
definition.inactiveDigSpeed=1
definition.digLevel=4
definition.activeDigSpeed=7
end
registerElectricChainsaw(definition)
})
industrialtest.ElectricChainsaw:register()
minetest.register_craft({
type="shaped",
output="industrialtest:electric_chainsaw",
@ -125,26 +60,28 @@ minetest.register_craft({
{"industrialtest:re_battery","industrialtest:refined_iron_ingot",""}
}
})
definition={
name="diamond_electric_chainsaw",
displayName=S("Diamond Electric Chainsaw")
industrialtest.AdvancedElectricChainsaw=table.copy(industrialtest.ElectricChainsawBase)
industrialtest.internal.unpackTableInto(industrialtest.AdvancedElectricChainsaw,{
name="industrialtest:advanced_electric_chainsaw",
description=S("Advanced Electric Chainsaw"),
inventoryImage="industrialtest_advanced_electric_chainsaw.png",
capacity=10000,
flow=industrialtest.api.lvPowerFlow,
digLevel=0,
digSpeedClass=5,
digSpeed=1,
active={
times={[1]=1.0,[2]=0.7,[3]=0.5,[4]=0.2},
digSpeed=8
}
if industrialtest.mtgAvailable then
definition.maxDropLevel=1
definition.inactiveTimes={[1]=10,[2]=5.6,[3]=4}
definition.maxLevel=3
definition.activeTimes={[1]=2.0,[2]=0.8,[3]=0.4}
elseif industrialtest.mclAvailable then
definition.digSpeedClass=5
definition.maxDropLevel=5
definition.inactiveDigSpeed=1
definition.digLevel=5
definition.activeDigSpeed=9
end
registerElectricChainsaw(definition)
})
industrialtest.AdvancedElectricChainsaw:register()
minetest.register_craft({
type="shaped",
output="industrialtest:diamond_electric_chainsaw",
output="industrialtest:advanced_electric_chainsaw",
recipe={
{"",industrialtest.elementKeys.diamond,""},
{industrialtest.elementKeys.diamond,"industrialtest:electric_chainsaw",industrialtest.elementKeys.diamond}

View File

@ -15,107 +15,41 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.ElectricDrillBase=table.copy(industrialtest.ActivatedElectricTool)
industrialtest.internal.unpackTableInto(industrialtest.ElectricDrillBase,{
digs={
"cracky",
"crumbly"
}
})
local electricDrill={}
electricDrill.afterUse=function(itemstack,config)
local meta=itemstack:get_meta()
industrialtest.api.addPowerToItem(itemstack,-20)
if meta:get_int("industrialtest.powerAmount")<20 then
itemstack:set_name("industrialtest:"..config.name)
end
return itemstack
function industrialtest.ElectricDrillBase.createDefinitionTable(self)
local def=industrialtest.ActivatedElectricTool.createDefinitionTable(self)
def.groups._industrialtest_miningDrill=1
return def
end
local function registerElectricDrill(config)
local definition={
description=config.displayName,
inventory_image="industrialtest_"..config.name..".png",
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=10000,
_industrialtest_powerFlow=industrialtest.api.lvPowerFlow,
_industrialtest_inactiveName="industrialtest:"..config.name
}
if industrialtest.mtgAvailable then
definition.tool_capabilities={
full_punch_interval=0.5,
max_drop_level=config.maxDropLevel,
groupcaps={
cracky={
times=config.inactiveTimes,
maxlevel=config.maxLevel
},
crumbly={
times=config.inactiveTimes,
maxlevel=config.maxLevel
}
}
}
definition.groups={
pickaxe=1,
shovel=1
}
elseif industrialtest.mclAvailable then
definition.tool_capabilities={
full_punch_interval=0.5,
max_drop_level=config.maxDropLevel
}
definition.groups={
tool=1,
dig_speed_class=config.digSpeedClass
}
definition.after_use=function()
-- Hack to make sure that drill won't be destroyed when has 0 EU in MCL
return nil
function industrialtest.ElectricDrillBase.getOpPower(self,itemstack)
return 50
end
definition._mcl_diggroups={
pickaxey={
speed=config.inactiveDigSpeed,
level=config.digLevel,
uses=-1
},
shovely={
speed=config.inactiveDigSpeed,
level=config.digLevel,
uses=-1
industrialtest.ElectricDrill=table.copy(industrialtest.ElectricDrillBase)
industrialtest.internal.unpackTableInto(industrialtest.ElectricDrill,{
name="industrialtest:electric_drill",
description=S("Electric Drill"),
inventoryImage="industrialtest_electric_drill.png",
capacity=30000,
flow=industrialtest.api.lvPowerFlow,
digLevel=1,
digSpeedClass=4,
active={
times={[1]=1.7,[2]=1.2,[3]=1.0,[4]=0.7},
digSpeed=4
}
}
definition._mcl_toollike_wield=true
end
minetest.register_tool("industrialtest:"..config.name,definition)
definition=table.copy(definition)
if industrialtest.mtgAvailable then
definition.tool_capabilities.groupcaps.cracky.times=config.activeTimes
definition.tool_capabilities.groupcaps.crumbly.times=config.activeTimes
elseif industrialtest.mclAvailable then
definition._mcl_diggroups.pickaxey.speed=config.activeDigSpeed
definition._mcl_diggroups.shovely.speed=config.activeDigSpeed
end
definition.groups.not_in_creative_inventory=1
definition.after_use=function(itemstack)
return electricDrill.afterUse(itemstack,config)
end
minetest.register_tool("industrialtest:"..config.name.."_active",definition)
industrialtest.internal.registeredElectricDrills["industrialtest:"..config.name]=true
industrialtest.internal.registeredElectricDrills["industrialtest:"..config.name.."_active"]=true
end
local definition={
name="electric_drill",
displayName=S("Electric Drill")
}
if industrialtest.mtgAvailable then
definition.maxDropLevel=1
definition.inactiveTimes={[1]=10,[2]=5.6,[3]=4}
definition.maxLevel=2
definition.activeTimes={[1]=2.0,[2]=0.8,[3]=0.4}
elseif industrialtest.mclAvailable then
definition.digSpeedClass=4
definition.maxDropLevel=4
definition.inactiveDigSpeed=1
definition.digLevel=4
definition.activeDigSpeed=7
end
registerElectricDrill(definition)
})
industrialtest.ElectricDrill:register()
minetest.register_craft({
type="shaped",
output="industrialtest:electric_drill",
@ -125,26 +59,27 @@ minetest.register_craft({
{"industrialtest:refined_iron_ingot","industrialtest:re_battery","industrialtest:refined_iron_ingot"}
}
})
definition={
name="diamond_electric_drill",
displayName=S("Diamond Electric Drill")
industrialtest.AdvancedElectricDrill=table.copy(industrialtest.ElectricDrillBase)
industrialtest.internal.unpackTableInto(industrialtest.AdvancedElectricDrill,{
name="industrialtest:advanced_electric_drill",
description=S("Advanced Electric Drill"),
inventoryImage="industrialtest_advanced_electric_drill.png",
capacity=30000,
flow=industrialtest.api.lvPowerFlow,
digLevel=0,
digSpeedClass=5,
active={
times={[1]=1.0,[2]=0.7,[3]=0.3,[4]=0.1},
digSpeed=7
}
if industrialtest.mtgAvailable then
definition.maxDropLevel=1
definition.inactiveTimes={[1]=10,[2]=5.6,[3]=4}
definition.maxLevel=3
definition.activeTimes={[1]=2.0,[2]=0.8,[3]=0.4}
elseif industrialtest.mclAvailable then
definition.digSpeedClass=5
definition.maxDropLevel=5
definition.inactiveDigSpeed=1
definition.digLevel=5
definition.activeDigSpeed=9
end
registerElectricDrill(definition)
})
industrialtest.AdvancedElectricDrill:register()
minetest.register_craft({
type="shaped",
output="industrialtest:diamond_electric_drill",
output="industrialtest:advanced_electric_drill",
recipe={
{"",industrialtest.elementKeys.diamond,""},
{industrialtest.elementKeys.diamond,"industrialtest:electric_drill",industrialtest.elementKeys.diamond}

View File

@ -0,0 +1,20 @@
-- 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 <http://www.gnu.org/licenses/>.
industrialtest.ElectricGearTool=table.copy(industrialtest.GearTool)
industrialtest.internal.unpackTableInto(industrialtest.ElectricGearTool,{
prepare=industrialtest.ElectricItem.prepare
})

View File

@ -15,30 +15,25 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.ElectricHoeBase=table.copy(industrialtest.ActivatedElectricTool)
industrialtest.internal.unpackTableInto(industrialtest.ElectricHoeBase,{
digs={"hoey"},
capacity=10000,
flow=industrialtest.api.lvPowerFlow
})
local electricHoe={}
electricHoe.afterUse=function(itemstack,config)
local meta=itemstack:get_meta()
industrialtest.api.addPowerToItem(itemstack,-20)
if meta:get_int("industrialtest.powerAmount")<20 then
itemstack:set_name("industrialtest:"..config.name)
end
return itemstack
end
local function registerElectricHoe(config)
local definition={
description=config.displayName,
inventory_image="industrialtest_"..config.name..".png",
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=10000,
_industrialtest_powerFlow=industrialtest.api.lvPowerFlow,
_industrialtest_inactiveName="industrialtest:"..config.name
}
function industrialtest.ElectricHoeBase.register(self)
if industrialtest.mtgAvailable then
self.define.onUse=true
elseif industrialtest.mclAvailable then
self.define.onPlace=true
end
industrialtest.ActivatedElectricTool.register(self)
end
function industrialtest.ElectricHoeBase.hitUse(self,itemstack,user,pointed)
-- Taken and adapted from farming mod from Minetest Game
local function onUse(user,pointed)
local pt = pointed
-- check if pointing at a node
if not pt then
@ -96,103 +91,59 @@ local function registerElectricHoe(config)
return true
end
definition.groups={
hoe=1
}
definition.on_use=function(itemstack,user,pointed)
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.powerAmount")>=20 and onUse(user,pointed) then
industrialtest.api.addPowerToItem(itemstack,-20)
return itemstack
end
return nil
end
elseif industrialtest.mclAvailable then
-- Taken from https://git.minetest.land/MineClone2/MineClone2/src/branch/master/mods/ITEMS/mcl_farming/hoes.lua#L3
local function createSoil(pos)
if pos == nil then
function industrialtest.ElectricHoeBase.use(self,itemstack,user,pointed)
local node=minetest.get_node(pointed.under)
if user and not user:get_player_control().sneak then
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
minetest.registered_nodes[node.name].on_rightclick(pointed.under,node,user,itemstack)
return false
end
local node = minetest.get_node(pos)
end
if minetest.is_protected(pointed.under, user:get_player_name()) then
minetest.record_protection_violation(pointed.under,user:get_player_name())
return false
end
-- Taken and adapted from https://git.minetest.land/MineClone2/MineClone2/src/branch/master/mods/ITEMS/mcl_farming/hoes.lua#L3
local name = node.name
local above = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z})
local above = minetest.get_node({x=pointed.under.x, y=pointed.under.y+1, z=pointed.under.z})
if minetest.get_item_group(name, "cultivatable") == 2 then
if above.name == "air" then
node.name = "mcl_farming:soil"
minetest.set_node(pos, node)
minetest.sound_play("default_dig_crumbly", { pos = pos, gain = 0.5 }, true)
minetest.set_node(pointed.under, node)
minetest.sound_play("default_dig_crumbly", { pos = pointed.under, gain = 0.5 }, true)
return true
end
elseif minetest.get_item_group(name, "cultivatable") == 1 then
if above.name == "air" then
node.name = "mcl_core:dirt"
minetest.set_node(pos, node)
minetest.sound_play("default_dig_crumbly", { pos = pos, gain = 0.6 }, true)
minetest.set_node(pointed.under, node)
minetest.sound_play("default_dig_crumbly", { pos = pointed.under, gain = 0.6 }, true)
return true
end
end
return false
end
definition.tool_capabilities={
full_punch_interval=0.5
function industrialtest.ElectricHoeBase.getOpPower(self,itemstack)
return 50
end
industrialtest.ElectricHoe=table.copy(industrialtest.ElectricHoeBase)
industrialtest.internal.unpackTableInto(industrialtest.ElectricHoe,{
name="industrialtest:electric_hoe",
description=S("Electric Hoe"),
inventoryImage="industrialtest_electric_hoe.png",
digLevel=0,
digSpeedClass=4,
active={
digSpeed=3
}
definition.groups={
tool=1
}
definition.on_place=function(itemstack,user,pointed)
local node=minetest.get_node(pointed.under)
if user and not user:get_player_control().sneak then
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
return minetest.registered_nodes[node.name].on_rightclick(pointed.under,node,user,itemstack) or itemstack
end
end
if minetest.is_protected(pointed.under, user:get_player_name()) then
minetest.record_protection_violation(pointed.under,user:get_player_name())
return nil
end
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.powerAmount")>=20 and createSoil(pointed.under) then
industrialtest.api.addPowerToItem(itemstack,-20)
return itemstack
end
return nil
end
definition.after_use=function(itemstack)
-- Hack to make sure that chainsaw won't be destroyed when has 0 EU in MCL
return nil
end
definition._mcl_toollike_wield=true
definition._mcl_diggroups={
hoey={
speed=config.inactiveDigSpeed,
level=config.digLevel,
uses=-1
}
}
end
minetest.register_tool("industrialtest:"..config.name,definition)
if industrialtest.mclAvailable then
definition=table.copy(definition)
definition._mcl_diggroups.hoey.speed=config.activeDigSpeed
definition.groups.not_in_creative_inventory=1
definition.after_use=function(itemstack)
return electricHoe.afterUse(itemstack,config)
end
minetest.register_tool("industrialtest:"..config.name.."_active",definition)
industrialtest.internal.registeredElectricHoes["industrialtest:"..config.name.."_active"]=true
end
industrialtest.internal.registeredElectricHoes["industrialtest:"..config.name]=true
end
local definition={
name="electric_hoe",
displayName=S("Electric Hoe")
}
if industrialtest.mclAvailable then
definition.inactiveDigSpeed=1
definition.digLevel=2
definition.activeDigSpeed=7
end
registerElectricHoe(definition)
})
industrialtest.ElectricHoe:register()
minetest.register_craft({
type="shaped",
output="industrialtest:electric_hoe",
@ -211,17 +162,25 @@ minetest.register_craft({
{"industrialtest:re_battery",""}
}
})
if industrialtest.mclAvailable then
registerElectricHoe({
name="diamond_electric_hoe",
displayName=S("Diamond Electric Hoe"),
inactiveDigSpeed=1,
digLevel=5,
activeDigSpeed=9
industrialtest.AdvancedElectricHoe=table.copy(industrialtest.ElectricHoeBase)
industrialtest.internal.unpackTableInto(industrialtest.AdvancedElectricHoe,{
name="industrialtest:advanced_electric_hoe",
description=S("Advanced Electric Hoe"),
inventoryImage="industrialtest_advanced_electric_hoe.png",
digLevel=0,
digSpeedClass=5,
active={
digSpeed=7
}
})
industrialtest.AdvancedElectricHoe:register()
minetest.register_craft({
type="shapeless",
output="industrialtest:diamond_electric_hoe",
output="industrialtest:advanced_electric_hoe",
recipe={
"industrialtest:electric_hoe",
industrialtest.elementKeys.diamond,

26
tools/electric_item.lua Normal file
View File

@ -0,0 +1,26 @@
-- 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 <http://www.gnu.org/licenses/>.
industrialtest.ElectricItem=table.copy(industrialtest.Item)
function industrialtest.ElectricItem.prepare(self,itemstack)
local meta=itemstack:get_meta()
if industrialtest.api.hasPowerStorage(meta) then
return
end
industrialtest.api.addPowerStorage(meta,self.capacity,self.flow,"n/a")
industrialtest.api.updateItemPowerText(itemstack)
end

View File

@ -14,162 +14,95 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- This entire code is super hacky, I'm aware.
local S=minetest.get_translator("industrialtest")
industrialtest.ElectricSaberBase=table.copy(industrialtest.ActivatedElectricTool)
industrialtest.internal.unpackTableInto(industrialtest.ElectricSaberBase,{
fullPunchInterval=0.5,
digs={"snappy"},
hits={"fleshy"},
capacity=100000,
flow=industrialtest.api.hvPowerFlow
})
local electricSaber={}
electricSaber.afterUse=function(itemstack,config)
local meta=itemstack:get_meta()
industrialtest.api.addPowerToItem(itemstack,-20)
if meta:get_int("industrialtest.powerAmount")<20 then
itemstack:set_name("industrialtest:"..config.name)
end
return itemstack
function industrialtest.ElectricSaberBase.createActiveDefinitionTable(self)
self.define.onUse=false
return industrialtest.ActivatedElectricTool.createActiveDefinitionTable(self)
end
local function registerElectricSaber(config)
local definition={
description=config.displayName,
inventory_image="industrialtest_"..config.name..".png",
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=10000,
_industrialtest_powerFlow=industrialtest.api.lvPowerFlow,
_industrialtest_inactiveName="industrialtest:"..config.name
}
if industrialtest.mtgAvailable then
definition.groups={
sword=1
}
definition.tool_capabilities={
full_punch_interval=0.5,
max_drop_level=config.maxDropLevel,
groupcaps={
snappy={
times=config.inactiveTimes,
maxlevel=config.maxLevel
}
},
damage_groups={fleshy=config.inactiveDamage}
}
elseif industrialtest.mclAvailable then
definition.groups={
weapon=1,
sword=1,
dig_speed_class=config.digSpeedClass
}
definition.tool_capabilities={
full_punch_interval=0.5,
max_drop_level=config.maxDropLevel,
damage_groups={fleshy=config.inactiveDamage}
}
definition.after_use=function()
-- Hack to make sure that saber won't be destroyed when has 0 EU in MCL
return nil
function industrialtest.ElectricSaberBase.hitUse(self,itemstack,user,pointed)
if self:canActivate(itemstack) and pointed.type=="object" then
-- pointed is a ObjectRef
industrialtest.api.addPowerToItem(itemstack,-self:getOpPower(itemstack))
local toolCapabilities={damage_groups={}}
for _,hitType in ipairs(self.hits) do
toolCapabilities.damage_groups[hitType]=self.active.damage
end
definition._mcl_toollike_wield=true
definition._mcl_diggroups={
swordy={
speed=config.inactiveDigSpeed,
level=config.digLevel,
uses=-1
},
swordy_cobweb={
speed=config.inactiveDigSpeed,
level=config.digLevel,
uses=-1
pointed.ref:punch(user,nil,toolCapabilities)
return true
end
return false
end
function industrialtest.ElectricSaberBase.afterUse(self,itemstack,user,node,digparams)
industrialtest.ActivatedElectricTool.afterUse(self,itemstack,user,node,digparams)
itemstack:set_name(self.name)
return true
end
function industrialtest.ElectricSaberBase.getOpPower(self,itemstack)
return 500
end
industrialtest.ElectricSaber=table.copy(industrialtest.ElectricSaberBase)
industrialtest.internal.unpackTableInto(industrialtest.ElectricSaber,{
name="industrialtest:electric_saber",
description=S("Electric Saber"),
inventoryImage="industrialtest_electric_saber.png",
digLevel=0,
digSpeedClass=4,
active={
digSpeed=7,
times={[1]=0.7,[2]=0.5,[3]=0.2,[4]=0.15},
damage=3
}
}
end
minetest.register_tool("industrialtest:"..config.name,definition)
definition=table.copy(definition)
if industrialtest.mtgAvailable then
definition.tool_capabilities.groupcaps.snappy.times=config.activeTimes
definition.tool_capabilities.damage_groups.fleshy=config.activeDamage
elseif industrialtest.mclAvailable then
definition.tool_capabilities.damage_groups.fleshy=config.activeDamage
definition._mcl_diggroups.swordy.speed=config.activeDigSpeed
definition._mcl_diggroups.swordy_cobweb.speed=config.activeDigSpeed
end
definition.groups.not_in_creative_inventory=1
definition.after_use=function(itemstack)
return electricSaber.afterUse(itemstack,config)
end
minetest.register_tool("industrialtest:"..config.name.."_active",definition)
industrialtest.internal.registeredElectricSabers["industrialtest:"..config.name]=true
industrialtest.internal.registeredElectricSabers["industrialtest:"..config.name.."_active"]=true
end
local definition={
name="electric_saber",
displayName=S("Electric Saber")
}
if industrialtest.mtgAvailable then
definition.maxDropLevel=1
definition.inactiveTimes={[1]=10,[2]=5.6,[3]=4}
definition.maxLevel=3
definition.inactiveDamage=1
definition.activeTimes={[1]=2.0,[2]=0.8,[3]=0.4}
definition.activeDamage=6
elseif industrialtest.mclAvailable then
definition.digSpeedClass=4
definition.maxDropLevel=4
definition.inactiveDamage=1
definition.inactiveDigSpeed=1
definition.digLevel=4
definition.activeDamage=6
definition.activeDigSpeed=7
end
registerElectricSaber(definition)
})
industrialtest.ElectricSaber:register()
minetest.register_craft({
type="shaped",
output="industrialtest:electric_saber",
recipe={
{"industrialtest:refined_iron_ingot"},
{"industrialtest:refined_iron_ingot"},
{"industrialtest:re_battery"}
{industrialtest.elementKeys.yellowDust,"industrialtest:advanced_alloy",""},
{industrialtest.elementKeys.yellowDust,"industrialtest:advanced_alloy",""},
{"industrialtest:carbon_plate","industrialtest:energy_crystal","industrialtest:carbon_plate"}
}
})
definition={
name="diamond_electric_saber",
displayName=S("Diamond Electric Saber")
industrialtest.AdvancedElectricSaber=table.copy(industrialtest.ElectricSaberBase)
industrialtest.internal.unpackTableInto(industrialtest.AdvancedElectricSaber,{
name="industrialtest:advanced_electric_saber",
description=S("Advanced Electric Saber"),
inventoryImage="industrialtest_advanced_electric_saber.png",
digLevel=0,
digSpeedClass=5,
active={
digSpeed=8,
times={[1]=0.5,[2]=0.2,[3]=0.15,[4]=0.1},
damage=5
}
if industrialtest.mtgAvailable then
definition.maxDropLevel=1
definition.inactiveTimes={[1]=10,[2]=5.6,[3]=4}
definition.maxLevel=3
definition.inactiveDamage=1
definition.activeTimes={[1]=2.0,[2]=0.8,[3]=0.4}
definition.activeDamage=9
elseif industrialtest.mclAvailable then
definition.digSpeedClass=5
definition.maxDropLevel=5
definition.inactiveDamage=1
definition.inactiveDigSpeed=1
definition.digLevel=5
definition.activeDamage=9
definition.activeDigSpeed=9
end
registerElectricSaber(definition)
})
industrialtest.AdvancedElectricSaber:register()
minetest.register_craft({
type="shapeless",
output="industrialtest:diamond_electric_saber",
output="industrialtest:advanced_electric_saber",
recipe={
"industrialtest:electric_saber",
industrialtest.elementKeys.diamond,
industrialtest.elementKeys.diamond
}
})
minetest.register_on_punchplayer(function(player,hitter)
local itemstack=hitter:get_wielded_item()
if industrialtest.internal.registeredElectricSabers[itemstack:get_name()] then
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.powerAmount")>=20 then
industrialtest.api.addPowerToItem(itemstack,-20)
hitter:set_wielded_item(itemstack)
local def=minetest.registered_tools[itemstack:get_name().."_active"]
player:set_hp(player:get_hp()-def.tool_capabilites.damage_groups.fleshy)
return true
end
end
return false
end)

76
tools/electric_tool.lua Normal file
View File

@ -0,0 +1,76 @@
-- 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 <http://www.gnu.org/licenses/>.
industrialtest.ElectricTool=table.copy(industrialtest.Tool)
industrialtest.internal.unpackTableInto(industrialtest.ElectricTool,{
prepare=industrialtest.ElectricItem.prepare
})
function industrialtest.ElectricTool.createDefinitionTable(self)
local def=industrialtest.Tool.createDefinitionTable(self)
def.after_use=function()
-- Hack to make sure that chainsaw won't be destroyed when has 0 EU
return nil
end
return def
end
function industrialtest.ElectricTool.onPlace(self,itemstack,user,pointed)
self:prepare(itemstack)
local meta=itemstack:get_meta()
local opPower=self:getOpPower(itemstack)
if meta:get_int("industrialtest.powerAmount")<opPower then
return false
end
if self:use(itemstack,user,pointed) then
industrialtest.api.addPowerToItem(itemstack,-opPower)
end
return true
end
function industrialtest.ElectricTool.onUse(self,itemstack,user,pointed)
self:prepare(itemstack)
if user:is_player() then
local controls=user:get_player_control()
if controls.sneak and self:changeMode(itemstack) then
return true
end
end
local meta=itemstack:get_meta()
local opPower=self:getOpPower(itemstack)
if meta:get_int("industrialtest.powerAmount")<opPower then
return false
end
if self:hitUse(itemstack,user,pointed) then
industrialtest.api.addPowerToItem(itemstack,-opPower)
end
return true
end
function industrialtest.ElectricTool.changeMode(self,itemstack)
-- dummy function
return false
end
function industrialtest.ElectricTool.getOpPower(self,itemstack)
-- dummy function
return 0
end

View File

@ -0,0 +1,27 @@
-- 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 <http://www.gnu.org/licenses/>.
industrialtest.FluidContainerItem=table.copy(industrialtest.Item)
function industrialtest.FluidContainerItem.prepare(self,itemstack)
if industrialtest.api.itemHasFluidStorage(itemstack) then
return
end
local meta=itemstack:get_meta()
meta:set_int("industrialtest.fluidAmount",0)
meta:set_int("industrialtest.fluidCapacity",self.capacity)
industrialtest.api.updateItemFluidText(itemstack)
end

45
tools/fluid_storage.lua Normal file
View File

@ -0,0 +1,45 @@
-- 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 <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.FuelCan=table.copy(industrialtest.FluidContainerItem)
industrialtest.internal.unpackTableInto(industrialtest.FuelCan,{
name="industrialtest:fuel_can",
description=S("Fuel Can"),
inventoryImage="industrialtest_fuel_can.png",
capacity=10000
})
function industrialtest.FuelCan.createDefinitionTable(self)
local def=industrialtest.FluidContainerItem.createDefinitionTable(self)
def.groups._industrialtest_fueled=1
def.groups._industrialtest_fuel=1
return def
end
industrialtest.FuelCan:register()
minetest.register_craft({
type="shaped",
output="industrialtest:fuel_can",
recipe={
{"","industrialtest:tin_plate","industrialtest:tin_plate"},
{"industrialtest:tin_plate","","industrialtest:tin_plate"},
{"industrialtest:tin_plate","industrialtest:tin_plate","industrialtest:tin_plate"}
}
})

72
tools/gear_tool.lua Normal file
View File

@ -0,0 +1,72 @@
-- 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 <http://www.gnu.org/licenses/>.
industrialtest.GearTool=table.copy(industrialtest.Item)
function industrialtest.GearTool.createDefinitionTable(self)
local def=industrialtest.Item.createDefinitionTable(self)
def.groups._industrialtest_gearTool=1
def.groups["armor_"..self.part]=1
if industrialtest.mtgAvailable then
def.groups.armor_heal=1
elseif industrialtest.mclAvailable then
def.groups.armor=1
def.groups.non_combat_armor=1
def.sounds={
_mcl_armor_equip="mcl_armor_equip_iron",
_mcl_armor_unequip="mcl_armor_unequip_iron"
}
def.on_place=mcl_armor.equip_on_use
def.on_secondary_use=mcl_armor.equip_on_use
def._mcl_armor_element=self.part
def._mcl_armor_texture=self.modelImage
end
return def
end
function industrialtest.GearTool.register(self)
local def=self:createDefinitionTable()
if industrialtest.mtgAvailable then
armor:register_armor(self.name,def)
elseif industrialtest.mclAvailable then
minetest.register_tool(self.name,def)
end
end
minetest.register_globalstep(function(dtime)
local players=minetest.get_connected_players()
for _,player in ipairs(players) do
local inv
if industrialtest.mtgAvailable then
_,inv=armor:get_valid_player(player,"")
elseif industrialtest.mclAvailable then
inv=player:get_inventory()
end
if inv then
local armorList=inv:get_list("armor")
assert(armorList)
for i,itemstack in ipairs(armorList) do
local def=itemstack:get_definition()
if def and def.groups._industrialtest_gearTool and def._industrialtest_self and def._industrialtest_self.update and
def._industrialtest_self:update(player,inv,itemstack,dtime) then
inv:set_stack("armor",i,itemstack)
end
end
end
end
end)

54
tools/item.lua Normal file
View File

@ -0,0 +1,54 @@
-- 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 <http://www.gnu.org/licenses/>.
industrialtest.Item={}
function industrialtest.Item.createDefinitionTable(self)
local def={
description=self.description,
inventory_image=self.inventoryImage,
groups={},
_industrialtest_self=self
}
if industrialtest.mtgAvailable then
def.groups.flammable=self.flammable
end
return def
end
function industrialtest.Item.register(self)
local def=self:createDefinitionTable()
minetest.register_tool(self.name,def)
end
-- Item callbacks
minetest.register_on_player_inventory_action(function(player,action,inventory,info)
if action=="put" then
local def=info.stack:get_definition()
if def and def._industrialtest_self and def._industrialtest_self.prepare then
def._industrialtest_self:prepare(info.stack)
inventory:set_stack(info.listname,info.index,info.stack)
end
end
end)
minetest.register_on_craft(function(itemstack)
local def=itemstack:get_definition()
if def and def._industrialtest_self and def._industrialtest_self.prepare then
def._industrialtest_self:prepare(itemstack)
end
end)

View File

@ -15,71 +15,39 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.JetpackBase=table.copy(industrialtest.GearTool)
industrialtest.internal.unpackTableInto(industrialtest.JetpackBase,{
part="torso"
})
local soundHandles = {}
local jetpack={}
local electricJetpack={}
local function registerJetpack(config)
if industrialtest.mclAvailable then
local groups={
armor=1,
non_combat_armor=1,
armor_torso=1,
non_combat_torso=1,
_industrialtest_jetpack=1
}
if config.groups then
for key,value in pairs(config.groups) do
groups[key]=value
function industrialtest.JetpackBase.update(self, player, inv, itemstack, dtime)
local playerName = player:get_player_name()
local control = player:get_player_control()
if control.jump and self:tryFly(itemstack) then
self.addYVelocityClamped(player,1,10)
if not soundHandles[playerName] then
local pos = player:get_pos()
local handle = minetest.sound_play("industrialtest_jetpack_loop", {
pos = pos,
gain = 1.0, -- Volume of the sound
max_hear_distance = 16, -- Maximum distance to hear the sound
object = player, -- Attach the sound to the player
loop = true, -- The sound is played in a loop
})
soundHandles[playerName] = handle
end
return true
else
if soundHandles[playerName] then
minetest.sound_stop(soundHandles[playerName])
soundHandles[playerName] = nil
end
end
local definition={
description=config.displayName,
inventory_image="industrialtest_"..config.name.."_inv.png",
groups=groups,
sounds={
_mcl_armor_equip="mcl_armor_equip_iron",
_mcl_armor_unequip="mcl_armor_unequip_iron"
},
on_place=mcl_armor.equip_on_use,
on_secondary_use=mcl_armor.equip_on_use,
_mcl_armor_element="torso",
_mcl_armor_texture="industrialtest_"..config.name..".png",
_industrialtest_tryFly=config.tryFly
}
if config.customKeys then
for key,value in pairs(config.customKeys) do
definition[key]=value
end
end
minetest.register_tool("industrialtest:"..config.name,definition)
elseif industrialtest.mtgAvailable then
local groups={
armor_torso=1,
armor_heal=0,
_industrialtest_jetpack=1
}
if config.groups then
for key,value in pairs(config.groups) do
groups[key]=value
end
end
local definition={
description=config.displayName,
inventory_image="industrialtest_"..config.name.."_inv.png",
groups=groups,
_industrialtest_tryFly=config.tryFly
}
if config.customKeys then
for key,value in pairs(config.customKeys) do
definition[key]=value
end
end
armor:register_armor("industrialtest:"..config.name,definition)
end
return false
end
local function addYVelocityClamped(player,vel,max)
function industrialtest.JetpackBase.addYVelocityClamped(player,vel,max)
local playerVel=player:get_velocity()
if playerVel.y+vel>max then
player:add_velocity(vector.new(0,math.max(max-playerVel.y,0),0))
@ -88,39 +56,33 @@ local function addYVelocityClamped(player,vel,max)
end
end
local function onGlobalStep(player,inv,itemstack,index,def)
if def.groups and def.groups._industrialtest_jetpack then
if def._industrialtest_tryFly(itemstack) then
addYVelocityClamped(player,1,10)
inv:set_stack("armor",index,itemstack)
end
return true
end
return false
industrialtest.Jetpack=table.copy(industrialtest.JetpackBase)
industrialtest.internal.unpackTableInto(industrialtest.Jetpack,{
-- _v is hack to suppress "Registered armor doesn't have material at the end of registration name" warning from 3D Armor.
name="industrialtest:jetpack_v",
description=S("Jetpack"),
inventoryImage="industrialtest_jetpack_v_inv.png",
modelImage="industrialtest_jetpack_v.png",
capacity=5000,
prepare=industrialtest.FluidContainerItem.prepare
})
function industrialtest.Jetpack.createDefinitionTable(self)
local def=industrialtest.JetpackBase.createDefinitionTable(self)
def.groups._industrialtest_fueled=1
return def
end
jetpack.tryFly=function(itemstack)
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.fluidAmount")==0 then
function industrialtest.Jetpack.tryFly(self,itemstack)
if industrialtest.api.isItemFluidStorageEmpty(itemstack) then
return false
end
industrialtest.api.addFluidToItem(itemstack,-1)
return true
end
-- _v is hack to suppress "Registered armor doesn't have material at the end of registration name" warning from 3D Armor.
registerJetpack({
name="jetpack_v",
displayName=S("Jetpack"),
groups={
_industrialtest_fueled=1,
_industrialtest_fluidStorage=1
},
tryFly=jetpack.tryFly,
customKeys={
_industrialtest_fluidCapacity=5000
}
})
industrialtest.Jetpack:register()
minetest.register_craft({
type="shaped",
output="industrialtest:jetpack_v",
@ -131,7 +93,18 @@ minetest.register_craft({
}
})
electricJetpack.tryFly=function(itemstack)
industrialtest.ElectricJetpack=table.copy(industrialtest.JetpackBase)
industrialtest.internal.unpackTableInto(industrialtest.ElectricJetpack,{
name="industrialtest:electric_jetpack",
description=S("Electric Jetpack"),
inventoryImage="industrialtest_electric_jetpack_inv.png",
modelImage="industrialtest_electric_jetpack.png",
flow=industrialtest.api.lvPowerFlow,
capacity=30000,
prepare=industrialtest.ElectricItem.prepare
})
function industrialtest.ElectricJetpack.tryFly(self,itemstack)
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.powerAmount")<10 then
return false
@ -140,16 +113,8 @@ electricJetpack.tryFly=function(itemstack)
return true
end
registerJetpack({
name="electric_jetpack",
displayName=S("Electric Jetpack"),
tryFly=electricJetpack.tryFly,
customKeys={
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=30000,
_industrialtest_powerFlow=industrialtest.api.lvPowerFlow
}
})
industrialtest.ElectricJetpack:register()
minetest.register_craft({
type="shaped",
output="industrialtest:electric_jetpack",
@ -159,32 +124,3 @@ minetest.register_craft({
{industrialtest.elementKeys.yellowDust,"",industrialtest.elementKeys.yellowDust}
}
})
minetest.register_globalstep(function(dtime)
-- FIXME: Maybe this can be optimized?
local players=minetest.get_connected_players()
for _,player in ipairs(players) do
local control=player:get_player_control()
if control.jump then
if industrialtest.mclAvailable then
local inv=player:get_inventory()
local stack=inv:get_stack("armor",3)
local def=stack:get_definition()
onGlobalStep(player,inv,stack,3,def)
elseif industrialtest.mtgAvailable then
local _,inv=armor:get_valid_player(player,"")
if inv then
local armorList=inv:get_list("armor")
assert(armorList)
for i=1,#armorList do
local stack=armorList[i]
local def=stack:get_definition()
if onGlobalStep(player,inv,stack,i,def) then
break
end
end
end
end
end
end
end)

View File

@ -15,10 +15,9 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.MiningLaserBeam={}
local beam={}
beam.onActivate=function(self,staticdata)
function industrialtest.MiningLaserBeam.onActivate(self,staticdata)
local data=minetest.deserialize(staticdata)
self.direction=data.direction
self.energy=data.energy
@ -28,11 +27,11 @@ beam.onActivate=function(self,staticdata)
self.user=data.user
end
beam.onPunch=function()
function industrialtest.MiningLaserBeam.onPunch()
return true
end
beam.onNodeBreak=function(pos,node,user)
function industrialtest.MiningLaserBeam.onNodeBreak(pos,node,user)
if industrialtest.mclAvailable then
local drops=minetest.get_node_drops(node.name,"")
for _, val in ipairs(drops) do
@ -45,7 +44,7 @@ beam.onNodeBreak=function(pos,node,user)
minetest.node_dig(pos,node,user)
end
beam.onStep=function(self,dtime,moveresult)
function industrialtest.MiningLaserBeam.onStep(self,dtime,moveresult)
local pos=self.object:get_pos()
if vector.distance(self.startPos,pos)>=self.distance or self.energy<=0 then
self.object:remove()
@ -67,7 +66,7 @@ beam.onStep=function(self,dtime,moveresult)
self.object:remove()
return
else
beam.onNodeBreak(val.node_pos,node,minetest.get_player_by_name(self.user))
industrialtest.MiningLaserBeam.onNodeBreak(val.node_pos,node,minetest.get_player_by_name(self.user))
self.energy=self.energy-1
end
elseif self.mode==4 then
@ -80,6 +79,7 @@ beam.onStep=function(self,dtime,moveresult)
end
end
-- Note: If there are more entities registered then replace manual registration with proper pseudo-OOP
minetest.register_entity("industrialtest:mining_laser_beam",{
initial_properties={
physical=true,
@ -103,18 +103,77 @@ minetest.register_entity("industrialtest:mining_laser_beam",{
static_save=false,
shaded=false,
},
on_activate=beam.onActivate,
on_punch=beam.onPunch,
on_step=beam.onStep
on_activate=industrialtest.MiningLaserBeam.onActivate,
on_punch=industrialtest.MiningLaserBeam.onPunch,
on_step=industrialtest.MiningLaserBeam.onStep
})
local miningLaser={}
miningLaser.mode1OpPower=1250
miningLaser.mode2OpPower=100
miningLaser.mode4OpPower=5000
miningLaser.modeCount=4
industrialtest.MiningLaser=table.copy(industrialtest.ElectricTool)
industrialtest.internal.unpackTableInto(industrialtest.MiningLaser,{
name="industrialtest:mining_laser",
description=S("Mining Laser (Mode 1)"),
inventoryImage="industrialtest_mining_laser.png",
capacity=300000,
flow=industrialtest.api.hvPowerFlow,
define={onUse=true},
_modeCount=4
})
miningLaser.getMode=function(itemstack)
function industrialtest.MiningLaser.hitUse(self,itemstack,user,pointed)
if not user:is_player() then
return false
end
local control=user:get_player_control()
if control.sneak then
end
local mode=self.getMode(itemstack)
local meta=itemstack:get_meta()
if mode==1 then
if not self:spawnBeam(itemstack,user,user:get_pos(),user:get_look_dir(),10,64) then
return false
end
elseif mode==2 then
if not self:spawnBeam(itemstack,user,user:get_pos(),user:get_look_dir(),3,2) then
return false
end
elseif mode==3 then
local yaw=user:get_look_horizontal()
local dir=vector.new(-math.sin(yaw),0,math.cos(yaw))
if not self:spawnBeam(itemstack,user,user:get_pos(),dir,10,64) then
return false
end
elseif mode==4 then
if not self:spawnBeam(itemstack,user,user:get_pos(),user:get_look_dir(),1,64) then
return false
end
end
return true
end
function industrialtest.MiningLaser.changeMode(self,itemstack)
local mode=self.getMode(itemstack)
mode=mode+1
if mode>=self._modeCount+1 then
mode=1
end
self.setMode(itemstack,mode)
return true
end
function industrialtest.MiningLaser.getOpPower(self,itemstack)
local mode=self.getMode(itemstack)
if mode==1 then
return 1250
elseif mode==2 or mode==3 then
return 100
elseif mode==4 then
return 5000
end
-- assert not reached
assert(false)
end
function industrialtest.MiningLaser.getMode(itemstack)
local meta=itemstack:get_meta()
if not meta:contains("mode") then
meta:set_int("mode",1)
@ -123,74 +182,26 @@ miningLaser.getMode=function(itemstack)
return meta:get_int("mode")
end
miningLaser.setMode=function(itemstack,mode)
function industrialtest.MiningLaser.setMode(itemstack,mode)
local meta=itemstack:get_meta()
meta:set_int("mode",mode)
meta:set_string("industrialtest.descriptionOverride",S("Mining Laser (Mode @1)",mode))
industrialtest.api.updateItemPowerText(itemstack)
end
miningLaser.spawnBeam=function(itemstack,user,pos,dir,opPower,energy,distance)
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.powerAmount")<opPower then
return false
end
function industrialtest.MiningLaser.spawnBeam(self,itemstack,user,pos,dir,energy,distance)
minetest.add_entity(pos+vector.new(0,1.5,0),"industrialtest:mining_laser_beam",minetest.serialize({
direction=dir,
energy=energy,
distance=distance,
mode=miningLaser.getMode(itemstack),
mode=self.getMode(itemstack),
user=user:get_player_name()
}))
industrialtest.api.addPowerToItem(itemstack,-opPower)
return true
end
miningLaser.onUse=function(itemstack,user)
if not user:is_player() then
return nil
end
local mode=miningLaser.getMode(itemstack)
local control=user:get_player_control()
if control.sneak then
mode=mode+1
if mode>=miningLaser.modeCount+1 then
mode=1
end
miningLaser.setMode(itemstack,mode)
return itemstack
end
local meta=itemstack:get_meta()
if mode==1 then
if not miningLaser.spawnBeam(itemstack,user,user:get_pos(),user:get_look_dir(),miningLaser.mode1OpPower,10,64) then
return nil
end
elseif mode==2 then
if not miningLaser.spawnBeam(itemstack,user,user:get_pos(),user:get_look_dir(),miningLaser.mode2OpPower,3,2) then
return nil
end
elseif mode==3 then
local yaw=user:get_look_horizontal()
local dir=vector.new(-math.sin(yaw),0,math.cos(yaw))
if not miningLaser.spawnBeam(itemstack,user,user:get_pos(),dir,miningLaser.mode1OpPower,10,64) then
return nil
end
elseif mode==4 then
if not miningLaser.spawnBeam(itemstack,user,user:get_pos(),user:get_look_dir(),miningLaser.mode4OpPower,1,64) then
return nil
end
end
return itemstack
end
industrialtest.MiningLaser:register()
minetest.register_tool("industrialtest:mining_laser",{
description=S("Mining Laser (Mode 1)"),
inventory_image="industrialtest_mining_laser.png",
on_use=miningLaser.onUse,
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=300000,
_industrialtest_powerFlow=industrialtest.api.hvPowerFlow
})
minetest.register_craft({
type="shaped",
output="industrialtest:mining_laser",

View File

@ -15,62 +15,66 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
local function registerNanoSuitPart(config)
local groups={
_industrialtest_nanoSuit=1
}
if config.element=="head" then
groups.armor_head=1
elseif config.element=="torso" then
groups.armor_torso=1
elseif config.element=="legs" then
groups.armor_legs=1
elseif config.element=="feet" then
groups.armor_feet=1
end
if industrialtest.mtgAvailable then
groups.armor_heal=0
armor:register_armor("industrialtest:"..config.name,{
description=config.displayName,
inventory_image="industrialtest_"..config.name.."_inv.png",
groups=groups,
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=1000000,
_industrialtest_powerFlow=industrialtest.api.evPowerFlow,
_industrialtest_damageReduction=config.damageReduction,
industrialtest_powerPerDamage=5000
})
elseif industrialtest.mclAvailable then
groups.armor=1
groups.non_combat_armor=1
minetest.register_tool("industrialtest:"..config.name,{
description=config.displayName,
inventory_image="industrialtest_"..config.name.."_inv.png",
groups=groups,
sounds={
_mcl_armor_equip="mcl_armor_equip_iron",
_mcl_armor_unequip="mcl_armor_unequip_iron"
},
on_place=mcl_armor.equip_on_use,
on_secondary_use=mcl_armor.equip_on_use,
_mcl_armor_element=config.element,
_mcl_armor_texture=(config.element=="feet" and "industrialtest_mcl_" or "industrialtest_")..config.name..".png",
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=1000000,
_industrialtest_powerFlow=industrialtest.api.evPowerFlow,
_industrialtest_damageReduction=config.damageReduction,
_industrialtest_powerPerDamage=5000
})
end
end
registerNanoSuitPart({
name="nano_helmet",
displayName=S("Nano Helmet"),
industrialtest.NanoSuit=table.copy(industrialtest.ElectricArmor)
industrialtest.internal.unpackTableInto(industrialtest.NanoSuit,{
name="industrialtest:nano",
elements={
{
name="helmet",
description=S("Nano Helmet"),
element="head",
damageReduction=0.12
inventoryImage="industrialtest_nano_helmet_inv.png",
texture="industrialtest_nano_helmet.png"
},
{
name="bodyarmor",
description=S("Nano Bodyarmor"),
element="torso",
inventoryImage="industrialtest_nano_bodyarmor_inv.png",
texture="industrialtest_nano_bodyarmor.png"
},
{
name="leggings",
description=S("Nano Leggings"),
element="legs",
inventoryImage="industrialtest_nano_leggings_inv.png",
texture="industrialtest_nano_leggings.png"
},
{
name="boots",
description=S("Nano Boots"),
element="feet",
inventoryImage="industrialtest_nano_boots_inv.png",
texture={
"industrialtest_nano_boots.png",
"industrialtest_mcl_nano_boots.png"
}
}
},
capacity=1000000,
flow=industrialtest.api.evPowerFlow
})
function industrialtest.NanoSuit.getReducedDamageForItem(self,itemstack)
local def=itemstack:get_definition()
if def.groups.armor_head then
return 0.12
elseif def.groups.armor_torso then
return 0.32
elseif def.groups.armor_legs then
return 0.3
elseif def.groups.armor_feet then
return 0.24
end
return 0
end
function industrialtest.NanoSuit.getPowerPerDamageForItem(self,itemstack)
return 5000
end
industrialtest.NanoSuit:register()
minetest.register_craft({
type="shaped",
output="industrialtest:nano_helmet",
@ -80,12 +84,6 @@ minetest.register_craft({
}
})
registerNanoSuitPart({
name="nano_bodyarmor",
displayName=S("Nano Bodyarmor"),
element="torso",
damageReduction=0.32
})
minetest.register_craft({
type="shaped",
output="industrialtest:nano_bodyarmor",
@ -96,12 +94,6 @@ minetest.register_craft({
}
})
registerNanoSuitPart({
name="nano_leggings",
displayName=S("Nano Leggings"),
element="legs",
damageReduction=0.3
})
minetest.register_craft({
type="shaped",
output="industrialtest:nano_leggings",
@ -112,12 +104,6 @@ minetest.register_craft({
}
})
registerNanoSuitPart({
name="nano_boots",
displayName=S("Nano Boots"),
element="feet",
damageReduction=0.24
})
minetest.register_craft({
type="shaped",
output="industrialtest:nano_boots",
@ -126,41 +112,3 @@ minetest.register_craft({
{"industrialtest:carbon_plate","industrialtest:energy_crystal","industrialtest:carbon_plate"}
}
})
minetest.register_on_player_hpchange(function(player,hpChange)
if hpChange>0 or not player:is_player() then
return hpChange
end
local inv
if industrialtest.mtgAvailable then
_,inv=armor:get_valid_player(player,"")
if not inv then
return hpChange
end
elseif industrialtest.mclAvailable then
inv=player:get_inventory()
end
local armorList=inv:get_list("armor")
assert(armorList)
local result=hpChange
for i=1,#armorList do
local stack=armorList[i]
local def=stack:get_definition()
if def.groups and def.groups._industrialtest_nanoSuit then
local meta=stack:get_meta()
local targetReducedDamage=math.floor(math.abs(hpChange)*def._industrialtest_damageReduction)
local requiredPower=targetReducedDamage*def._industrialtest_powerPerDamage
local availablePower=math.min(meta:get_int("industrialtest.powerAmount"),requiredPower)
local reducedDamage=math.floor(availablePower/def._industrialtest_powerPerDamage)
if reducedDamage>0 then
result=result+reducedDamage
industrialtest.api.addPowerToItem(stack,-reducedDamage*def._industrialtest_powerPerDamage)
inv:set_stack("armor",i,stack)
end
end
end
return result
end,true)

101
tools/power_storage.lua Normal file
View File

@ -0,0 +1,101 @@
-- 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 <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.REBattery=table.copy(industrialtest.ElectricItem)
industrialtest.internal.unpackTableInto(industrialtest.REBattery,{
name="industrialtest:re_battery",
description=S("RE-Battery"),
inventoryImage="industrialtest_re_battery.png",
capacity=7000,
flow=industrialtest.api.lvPowerFlow
})
industrialtest.REBattery:register()
minetest.register_craft({
type="shaped",
output="industrialtest:re_battery",
recipe={
{"","industrialtest:insulated_tin_cable",""},
{industrialtest.elementKeys.tinIngot,industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.tinIngot},
{industrialtest.elementKeys.tinIngot,industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.tinIngot}
}
})
industrialtest.AdvancedREBattery=table.copy(industrialtest.ElectricItem)
industrialtest.internal.unpackTableInto(industrialtest.AdvancedREBattery,{
name="industrialtest:advanced_re_battery",
description=S("Advanced RE-Battery"),
inventoryImage="industrialtest_advanced_re_battery.png",
capacity=100000,
flow=industrialtest.api.mvPowerFlow
})
industrialtest.AdvancedREBattery:register()
minetest.register_craft({
type="shaped",
output="industrialtest:advanced_re_battery",
recipe={
{"industrialtest:insulated_copper_cable",industrialtest.elementKeys.bronzeIngot,"industrialtest:insulated_copper_cable"},
{industrialtest.elementKeys.bronzeIngot,"industrialtest:sulfur_dust",industrialtest.elementKeys.bronzeIngot},
{industrialtest.elementKeys.bronzeIngot,"industrialtest:lead_dust",industrialtest.elementKeys.bronzeIngot}
}
})
industrialtest.EnergyCrystal=table.copy(industrialtest.ElectricItem)
industrialtest.internal.unpackTableInto(industrialtest.EnergyCrystal,{
name="industrialtest:energy_crystal",
description=S("Energy Crystal"),
inventoryImage="industrialtest_energy_crystal.png",
capacity=1000000,
flow=industrialtest.api.hvPowerFlow
})
industrialtest.EnergyCrystal:register()
minetest.register_craft({
type="shaped",
output="industrialtest:energy_crystal",
recipe={
{industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.powerCarrier},
{industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.diamond,industrialtest.elementKeys.powerCarrier},
{industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.powerCarrier,industrialtest.elementKeys.powerCarrier}
}
})
industrialtest.LapotronCrystal=table.copy(industrialtest.ElectricItem)
industrialtest.internal.unpackTableInto(industrialtest.LapotronCrystal,{
name="industrialtest:lapotron_crystal",
description=S("Lapotron Crystal"),
inventoryImage="industrialtest_lapotron_crystal.png",
capacity=10000000,
flow=industrialtest.api.evPowerFlow
})
industrialtest.LapotronCrystal:register()
minetest.register_craft({
type="shaped",
output="industrialtest:lapotron_crystal",
recipe={
{industrialtest.elementKeys.blueDye,"industrialtest:electronic_circuit",industrialtest.elementKeys.blueDye},
{industrialtest.elementKeys.blueDye,"industrialtest:energy_crystal",industrialtest.elementKeys.blueDye},
{industrialtest.elementKeys.blueDye,"industrialtest:electronic_circuit",industrialtest.elementKeys.blueDye}
}
})

View File

@ -16,61 +16,212 @@
local S=minetest.get_translator("industrialtest")
local quantumSuit={}
quantumSuit.helmetBreathRefillOpPower=1000
quantumSuit.leggingsSpeedOpPower=125
quantumSuit.leggingsSpeedMaxVel=4
quantumSuit.bootsJumpOpPower=50
quantumSuit.bootsFallDamageReductionOpPower=900
industrialtest.QuantumArmorBase=table.copy(industrialtest.ElectricGearTool)
industrialtest.internal.unpackTableInto(industrialtest.QuantumArmorBase,{
flow=industrialtest.api.ivPowerFlow,
capacity=10000000
})
function industrialtest.QuantumArmorBase.createDefintionTable(self)
local def=industrialtest.ElectricGearTool.createDefintionTable(self)
def.groups._industrialtest_electricArmor=1
return def
end
function industrialtest.QuantumArmorBase.getPowerPerDamageForItem(self,itemstack)
return 30
end
industrialtest.QuantumHelmet=table.copy(industrialtest.QuantumArmorBase)
industrialtest.internal.unpackTableInto(industrialtest.QuantumHelmet,{
name="industrialtest:quantum_helmet",
description=S("Quantum Helmet"),
inventoryImage="industrialtest_quantum_helmet_inv.png",
part="head",
modelImage="industrialtest_quantum_helmet.png",
_breathRefillOpPower=1000
})
local quantumHelmetUpdateDelta=0
function industrialtest.QuantumHelmet.update(self,player,inv,itemstack,dtime)
quantumHelmetUpdateDelta=quantumHelmetUpdateDelta+dtime
if quantumHelmetUpdateDelta<industrialtest.config.updateDelay then
return false
end
quantumHelmetUpdateDelta=0
if player:get_breath()<10 then
local meta=itemstack:get_meta()
local refilled=math.min(9-player:get_breath(),math.floor(meta:get_int("industrialtest.powerAmount")/self._breathRefillOpPower))
if refilled>0 then
player:set_breath(player:get_breath()+refilled)
industrialtest.api.addPowerToItem(itemstack,-refilled*self._breathRefillOpPower)
return true
end
end
return false
end
function industrialtest.QuantumHelmet.getReducedDamageForItem(self,itemstack)
return 0.15
end
industrialtest.QuantumHelmet:register()
minetest.register_craft({
type="shaped",
output="industrialtest:quantum_helmet",
recipe={
{"industrialtest:reinforced_glass","industrialtest:nano_helmet","industrialtest:reinforced_glass"},
{"industrialtest:iridium_plate","industrialtest:lapotron_crystal","industrialtest:iridium_plate"},
{"industrialtest:advanced_electronic_circuit","industrialtest:empty_cell","industrialtest:advanced_electronic_circuit"}
}
})
industrialtest.QuantumBodyarmor=table.copy(industrialtest.QuantumArmorBase)
industrialtest.internal.unpackTableInto(industrialtest.QuantumBodyarmor,{
name="industrialtest:quantum_bodyarmor",
description=S("Quantum Bodyarmor"),
inventoryImage="industrialtest_quantum_bodyarmor_inv.png",
part="torso",
modelImage="industrialtest_quantum_bodyarmor.png",
update=industrialtest.JetpackBase.update,
addYVelocityClamped=industrialtest.JetpackBase.addYVelocityClamped,
tryFly=industrialtest.ElectricJetpack.tryFly
})
function industrialtest.QuantumBodyarmor.getReducedDamageForItem(self,itemstack)
return 0.4
end
industrialtest.QuantumBodyarmor:register()
minetest.register_craft({
type="shaped",
output="industrialtest:quantum_bodyarmor",
recipe={
{"industrialtest:advanced_alloy","industrialtest:nano_bodyarmor","industrialtest:advanced_alloy"},
{"industrialtest:iridium_plate","industrialtest:lapotron_crystal","industrialtest:iridium_plate"},
{"industrialtest:iridium_plate","industrialtest:electric_jetpack","industrialtest:iridium_plate"}
}
})
industrialtest.QuantumLeggings=table.copy(industrialtest.QuantumArmorBase)
industrialtest.internal.unpackTableInto(industrialtest.QuantumLeggings,{
name="industrialtest:quantum_leggings",
description=S("Quantum Leggings"),
inventoryImage="industrialtest_quantum_leggings_inv.png",
part="legs",
modelImage="industrialtest_quantum_leggings.png",
_speedOpPower=125,
_speedMaxVel=4
})
local leggingsSpeedEnabled={}
local playerPositions={}
local playerLeggingsSpeedEnabled={}
local playerBootsJumpEnabled={}
function industrialtest.QuantumLeggings.update(self,player,inv,itemstack,dtime)
local control=player:get_player_control()
local playerName=player:get_player_name()
if leggingsSpeedEnabled[playerName] then
if control.up and control.aux1 then
local meta=itemstack:get_meta()
local requiredPower=vector.distance(player:get_pos(),playerPositions[playerName])*self._speedOpPower
if meta:get_int("industrialtest.powerAmount")>=requiredPower then
industrialtest.api.addPowerToItem(itemstack,-requiredPower)
playerPositions[playerName]=player:get_pos()
return true
end
end
player:set_physics_override({
speed=1
})
leggingsSpeedEnabled[playerName]=false
elseif control.up and control.aux1 then
local meta=itemstack:get_meta()
local requiredPower=vector.distance(player:get_pos(),playerPositions[playerName])*self._speedOpPower
if meta:get_int("industrialtest.powerAmount")>=requiredPower then
player:set_physics_override({
speed=self._speedMaxVel
})
leggingsSpeedEnabled[playerName]=true
end
end
playerPositions[playerName]=player:get_pos()
return false
end
local function registerQuantumSuitPart(config)
config.groups=config.groups or {}
config.groups._industrialtest_nanoSuit=1
if config.element=="head" then
config.groups.armor_head=1
elseif config.element=="torso" then
config.groups.armor_torso=1
elseif config.element=="legs" then
config.groups.armor_legs=1
elseif config.element=="feet" then
config.groups.armor_feet=1
function industrialtest.QuantumLeggings.getReducedDamageForItem(self,itemstack)
return 0.3
end
local definition={
description=config.displayName,
inventory_image="industrialtest_"..config.name.."_inv.png",
groups=config.groups,
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=10000000,
_industrialtest_powerFlow=industrialtest.api.ivPowerFlow,
_industrialtest_damageReduction=config.damageReduction,
_industrialtest_powerPerDamage=30
industrialtest.QuantumLeggings:register()
minetest.register_craft({
type="shaped",
output="industrialtest:quantum_leggings",
recipe={
{"industrialtest:machine_block","industrialtest:lapotron_crystal","industrialtest:machine_block"},
{"industrialtest:iridium_plate","industrialtest:nano_leggings","industrialtest:iridium_plate"},
{industrialtest.elementKeys.yellowDust,"",industrialtest.elementKeys.yellowDust}
}
if config.customKeys then
for k,v in pairs(config.customKeys) do
definition[k]=v
})
industrialtest.QuantumBoots=table.copy(industrialtest.QuantumArmorBase)
industrialtest.internal.unpackTableInto(industrialtest.QuantumBoots,{
name="industrialtest:quantum_boots",
description=S("Quantum Boots"),
inventoryImage="industrialtest_quantum_boots_inv.png",
part="feet",
modelImage=(industrialtest.mclAvailable and "industrialtest_mcl_quantum_leggings.png" or "industrialtest_quantum_leggings.png"),
_jumpOpPower=50,
_jumpPower=2,
_fallDamageReductionOpPower=900,
})
local bootsJumpEnabled={}
function industrialtest.QuantumBoots.update(self,player,inv,itemstack,dtime)
local control=player:get_player_control()
local playerName=player:get_player_name()
if bootsJumpEnabled[playerName] then
local shouldStopJump=not control.aux1
if control.jump and control.aux1 then
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.powerAmount")>=self._jumpOpPower then
industrialtest.api.addPowerToItem(itemstack,-self._jumpOpPower)
return true
end
end
if industrialtest.mtgAvailable then
definition.groups.armor_heal=0
armor:register_armor("industrialtest:"..config.name,definition)
elseif industrialtest.mclAvailable then
definition.groups.armor=1
definition.groups.non_combat_armor=1
definition.sounds={
_mcl_armor_equip="mcl_armor_equip_iron",
_mcl_armor_unequip="mcl_armor_unequip_iron"
player:set_physics_override({
jump=1
})
bootsJumpEnabled[playerName]=false
elseif control.aux1 then
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.powerAmount")>=self._jumpOpPower then
player:set_physics_override({
jump=self._jumpPower
})
bootsJumpEnabled[playerName]=true
end
end
return false
end
function industrialtest.QuantumBoots.getReducedDamageForItem(self,itemstack)
return 0.15
end
industrialtest.QuantumBoots:register()
minetest.register_craft({
type="shaped",
output="industrialtest:quantum_boots",
recipe={
{"industrialtest:iridium_plate","industrialtest:nano_boots","industrialtest:iridium_plate"},
{industrialtest.elementKeys.ironBoots,"industrialtest:lapotron_crystal",industrialtest.elementKeys.ironBoots}
}
definition.on_place=mcl_armor.equip_on_use
definition.on_secondary_use=mcl_armor.equip_on_use
definition._mcl_armor_element=config.element
definition._mcl_armor_texture=(config.element=="feet" and "industrialtest_mcl_" or "industrialtest_")..config.name..".png"
minetest.register_tool("industrialtest:"..config.name,definition)
end
end
})
local function findInPlayerArmorList(player,itemname)
local inv
@ -87,174 +238,6 @@ local function findInPlayerArmorList(player,itemname)
end
end
quantumSuit.tryFly=function(itemstack)
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.powerAmount")<10 then
return false
end
industrialtest.api.addPowerToItem(itemstack,-10)
return true
end
registerQuantumSuitPart({
name="quantum_helmet",
displayName=S("Quantum Helmet"),
element="head",
damageReduction=0.15
})
minetest.register_craft({
type="shaped",
output="industrialtest:quantum_helmet",
recipe={
{"industrialtest:reinforced_glass","industrialtest:nano_helmet","industrialtest:reinforced_glass"},
{"industrialtest:iridium_plate","industrialtest:lapotron_crystal","industrialtest:iridium_plate"},
{"industrialtest:advanced_electronic_circuit","industrialtest:empty_cell","industrialtest:advanced_electronic_circuit"}
}
})
registerQuantumSuitPart({
name="quantum_bodyarmor",
displayName=S("Quantum Bodyarmor"),
element="torso",
damageReduction=0.4,
groups={
_industrialtest_jetpack=1
},
customKeys={
_industrialtest_tryFly=quantumSuit.tryFly
}
})
minetest.register_craft({
type="shaped",
output="industrialtest:quantum_bodyarmor",
recipe={
{"industrialtest:advanced_alloy","industrialtest:nano_bodyarmor","industrialtest:advanced_alloy"},
{"industrialtest:iridium_plate","industrialtest:lapotron_crystal","industrialtest:iridium_plate"},
{"industrialtest:iridium_plate","industrialtest:electric_jetpack","industrialtest:iridium_plate"}
}
})
registerQuantumSuitPart({
name="quantum_leggings",
displayName=S("Quantum Leggings"),
element="legs",
damageReduction=0.30
})
minetest.register_craft({
type="shaped",
output="industrialtest:quantum_leggings",
recipe={
{"industrialtest:machine_block","industrialtest:lapotron_crystal","industrialtest:machine_block"},
{"industrialtest:iridium_plate","industrialtest:nano_leggings","industrialtest:iridium_plate"},
{industrialtest.elementKeys.yellowDust,"",industrialtest.elementKeys.yellowDust}
}
})
registerQuantumSuitPart({
name="quantum_boots",
displayName=S("Quantum Boots"),
element="feet",
damageReduction=0.15
})
minetest.register_craft({
type="shaped",
output="industrialtest:quantum_boots",
recipe={
{"industrialtest:iridium_plate","industrialtest:nano_boots","industrialtest:iridium_plate"},
{industrialtest.elementKeys.ironBoots,"industrialtest:lapotron_crystal",industrialtest.elementKeys.ironBoots}
}
})
minetest.register_globalstep(function(dtime)
local players=minetest.get_connected_players()
for _,player in ipairs(players) do
local control=player:get_player_control()
local playerName=player:get_player_name()
if playerLeggingsSpeedEnabled[playerName] then
local shouldStopSpeed=true
if control.up and control.aux1 then
local index,stack,inv=findInPlayerArmorList(player,"industrialtest:quantum_leggings")
if index and stack and inv then
local meta=stack:get_meta()
local requiredPower=vector.distance(player:get_pos(),playerPositions[playerName])*quantumSuit.leggingsSpeedOpPower
if meta:get_int("industrialtest.powerAmount")>=requiredPower then
industrialtest.api.addPowerToItem(stack,-requiredPower)
inv:set_stack("armor",index,stack)
shouldStopSpeed=false
end
end
end
if shouldStopSpeed then
player:set_physics_override({
speed=1
})
playerLeggingsSpeedEnabled[playerName]=false
end
elseif control.up and control.aux1 then
local index,stack,inv=findInPlayerArmorList(player,"industrialtest:quantum_leggings")
if index and stack and inv then
local meta=stack:get_meta()
local requiredPower=vector.distance(player:get_pos(),playerPositions[playerName])*quantumSuit.leggingsSpeedOpPower
if meta:get_int("industrialtest.powerAmount")>=requiredPower then
player:set_physics_override({
speed=quantumSuit.leggingsSpeedMaxVel
})
playerLeggingsSpeedEnabled[playerName]=true
end
end
end
if playerBootsJumpEnabled[playerName] then
local shouldStopJump=not control.aux1
if control.jump and control.aux1 then
local index,stack,inv=findInPlayerArmorList(player,"industrialtest:quantum_boots")
if index and stack and inv then
local meta=stack:get_meta()
if meta:get_int("industrialtest.powerAmount")>=quantumSuit.bootsJumpOpPower then
industrialtest.api.addPowerToItem(stack,-quantumSuit.bootsJumpOpPower)
inv:set_stack("armor",index,stack)
shouldStopJump=false
end
end
end
if shouldStopJump then
player:set_physics_override({
jump=1
})
playerBootsJumpEnabled[playerName]=false
end
elseif control.aux1 then
local index,stack,inv=findInPlayerArmorList(player,"industrialtest:quantum_boots")
if index and stack and inv then
local meta=stack:get_meta()
local requiredPower=vector.distance(player:get_pos(),playerPositions[playerName])*quantumSuit.leggingsSpeedOpPower
if meta:get_int("industrialtest.powerAmount")>=quantumSuit.bootsJumpOpPower then
player:set_physics_override({
jump=2
})
playerBootsJumpEnabled[playerName]=true
end
end
end
if player:get_breath()<10 then
local index,stack,inv=findInPlayerArmorList(player,"industrialtest:quantum_helmet")
if index and stack and inv then
local meta=stack:get_meta()
local refilled=math.min(9-player:get_breath(),math.floor(meta:get_int("industrialtest.powerAmount")/quantumSuit.helmetBreathRefillOpPower))
if refilled>0 then
player:set_breath(player:get_breath()+refilled)
industrialtest.api.addPowerToItem(stack,-refilled*quantumSuit.helmetBreathRefillOpPower)
inv:set_stack("armor",index,stack)
end
end
end
playerPositions[playerName]=player:get_pos()
end
end)
minetest.register_on_player_hpchange(function(player,hpChange,reason)
if reason.type~="fall" then
return hpChange
@ -267,8 +250,8 @@ minetest.register_on_player_hpchange(function(player,hpChange,reason)
local damage=math.abs(hpChange)
local meta=stack:get_meta()
local reducedDamage=math.min(damage,math.floor(meta:get_int("industrialtest.powerAmount")/(damage*quantumSuit.bootsFallDamageReductionOpPower)))
industrialtest.api.addPowerToItem(stack,-reducedDamage*quantumSuit.bootsFallDamageReductionOpPower)
local reducedDamage=math.min(damage,math.floor(meta:get_int("industrialtest.powerAmount")/(damage*industrialtest.QuantumBoots._fallDamageReductionOpPower)))
industrialtest.api.addPowerToItem(stack,-reducedDamage*industrialtest.QuantumBoots._fallDamageReductionOpPower)
inv:set_stack("armor",index,stack)
return hpChange+reducedDamage

152
tools/scanner.lua Normal file
View File

@ -0,0 +1,152 @@
-- 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 <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.Scanner=table.copy(industrialtest.ElectricTool)
industrialtest.internal.unpackTableInto(industrialtest.Scanner,{
define={onUse=true}
})
function industrialtest.Scanner.createDefinitionTable(self)
local def=industrialtest.ElectricTool.createDefinitionTable(self)
def.groups._industrialtest_scanner=1
return def
end
-- Used by Miner to provide Scanner functionality there
function industrialtest.Scanner.filter(self,pos)
-- dummy function
return {}
end
industrialtest.OreScanner=table.copy(industrialtest.Scanner)
function industrialtest.OreScanner.hitUse(self,itemstack,user,pointed)
if not user:is_player() then
return false
end
local positions=""
local pos=user:get_pos()
for x=pos.x-self.distance,pos.x+self.distance do
for y=pos.y-self.distance,pos.y+self.distance do
for z=pos.z-self.distance,pos.z+self.distance do
local targetPos=vector.new(x,y,z)
local node=minetest.get_node(targetPos)
if self.isOre(node) then
positions=positions..string.format("%d %d %d",x,y,z)
positions=positions..","
end
end
end
end
local formspec={
"formspec_version[4]",
"size[10.5,11]",
"label[0.5,0.5;"..self.description.."]",
"label[0.5,1.7;"..S("Found ores").."]",
"textlist[0.5,1.9;9.5,8.6;pos;"..positions.."]"
}
local content=table.concat(formspec,"")
minetest.show_formspec(user:get_player_name(),"industrialtest:scanner",content)
return true
end
function industrialtest.OreScanner.filter(self,pos)
local result={}
for x=pos.x-self.minerDistance,pos.x+self.minerDistance do
for z=pos.z-self.minerDistance,pos.z+self.minerDistance do
local nodePos=vector.new(x,pos.y,z)
local node=minetest.get_node(nodePos)
-- This is very hacky, but currently there is no other way of determining if node is ore
if (x~=pos.x or z~=pos.z) and self.isOre(node) then
table.insert(result,nodePos)
end
end
end
return result
end
function industrialtest.OreScanner.isOre(node)
return string.find(node.name,":stone_with_")
end
industrialtest.ODScanner=table.copy(industrialtest.OreScanner)
industrialtest.internal.unpackTableInto(industrialtest.ODScanner,{
name="industrialtest:od_scanner",
description=S("OD Scanner"),
inventoryImage="industrialtest_od_scanner.png",
capacity=100000,
flow=industrialtest.api.lvPowerFlow,
distance=7,
minerDistance=3
})
function industrialtest.ODScanner.getOpPower(self,itemstack)
return 700
end
industrialtest.ODScanner:register()
minetest.register_craft({
type="shaped",
output="industrialtest:od_scanner",
recipe={
{"",industrialtest.elementKeys.yellowDust,""},
{"industrialtest:electronic_circuit","industrialtest:re_battery","industrialtest:electronic_circuit"},
{"industrialtest:insulated_copper_cable","industrialtest:insulated_copper_cable","industrialtest:insulated_copper_cable"}
}
})
industrialtest.OVScanner=table.copy(industrialtest.OreScanner)
industrialtest.internal.unpackTableInto(industrialtest.OVScanner,{
name="industrialtest:ov_scanner",
description=S("OV Scanner"),
inventoryImage="industrialtest_ov_scanner.png",
capacity=1000000,
flow=industrialtest.api.mvPowerFlow,
distance=11,
minerDistance=5
})
function industrialtest.OVScanner.getOpPower(self,itemstack)
return 7000
end
industrialtest.OVScanner:register()
minetest.register_craft({
type="shaped",
output="industrialtest:ov_scanner",
recipe={
{"",industrialtest.elementKeys.yellowDust,""},
{industrialtest.elementKeys.yellowDust,"industrialtest:electronic_circuit",industrialtest.elementKeys.yellowDust},
{"industrialtest:insulated_gold_cable","industrialtest:od_scanner","industrialtest:insulated_gold_cable"}
}
})
minetest.register_craft({
type="shaped",
output="industrialtest:ov_scanner",
recipe={
{"",industrialtest.elementKeys.yellowDust,""},
{industrialtest.elementKeys.yellowDust,"industrialtest:electronic_circuit",industrialtest.elementKeys.yellowDust},
{"industrialtest:insulated_gold_cable","industrialtest:re_battery","industrialtest:insulated_gold_cable"}
}
})

View File

@ -15,58 +15,41 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.SolarHelmet=table.copy(industrialtest.GearTool)
industrialtest.internal.unpackTableInto(industrialtest.SolarHelmet,{
name="industrialtest:solar_helmet",
description=S("Solar Helmet"),
inventoryImage="industrialtest_solar_helmet_inv.png",
part="head",
modelImage="industrialtest_solar_helmet.png"
})
local updateDelta=0
local function onGlobalStep(player,inv,stack)
if stack:get_name()~="industrialtest:solar_helmet" then
function industrialtest.SolarHelmet.update(self,player,inv,itemstack,dtime)
updateDelta=updateDelta+dtime
if updateDelta<industrialtest.config.updateDelay then
return false
end
updateDelta=0
local amount=math.floor((minetest.get_node_light(player:get_pos()) or 0)/2)
if amount==0 then
return true
return false
end
local armorList=inv:get_list("armor")
for i=1,#armorList do
local meta=armorList[i]:get_meta()
for i,armorItemstack in ipairs(armorList) do
local meta=armorItemstack:get_meta()
if industrialtest.api.hasPowerStorage(meta) and not industrialtest.api.isFullyCharged(meta) then
industrialtest.api.addPowerToItem(armorList[i],amount)
inv:set_stack("armor",i,armorList[i])
industrialtest.api.addPowerToItem(armorItemstack,amount)
inv:set_stack("armor",i,armorItemstack)
break
end
end
return true
return false
end
if industrialtest.mtgAvailable then
armor:register_armor("industrialtest:solar_helmet",{
description=S("Solar Helmet"),
inventory_image="industrialtest_solar_helmet_inv.png",
groups={
armor_head=1,
armor_heal=0
}
})
elseif industrialtest.mclAvailable then
minetest.register_tool("industrialtest:solar_helmet",{
description=S("Solar Helmet"),
inventory_image="industrialtest_solar_helmet_inv.png",
groups={
armor=1,
non_combat_armor=1,
armor_head=1,
non_combat_feet=1
},
sounds={
_mcl_armor_equip="mcl_armor_equip_iron",
_mcl_armor_unequip="mcl_armor_unequip_iron"
},
on_place=mcl_armor.equip_on_use,
on_secondary_use=mcl_armor.equip_on_use,
_mcl_armor_element="head",
_mcl_armor_texture="industrialtest_solar_helmet.png"
})
end
industrialtest.SolarHelmet:register()
minetest.register_craft({
type="shaped",
output="industrialtest:solar_helmet",
@ -76,6 +59,7 @@ minetest.register_craft({
{"industrialtest:insulated_copper_cable","industrialtest:insulated_copper_cable","industrialtest:insulated_copper_cable"}
}
})
minetest.register_craft({
type="shaped",
output="industrialtest:solar_helmet",
@ -85,31 +69,3 @@ minetest.register_craft({
{"industrialtest:insulated_copper_cable","industrialtest:insulated_copper_cable","industrialtest:insulated_copper_cable"}
}
})
minetest.register_globalstep(function(dtime)
updateDelta=updateDelta+dtime
if updateDelta<industrialtest.updateDelay then
return
end
updateDelta=0
local players=minetest.get_connected_players()
for _,player in ipairs(players) do
if industrialtest.mtgAvailable then
local _,inv=armor:get_valid_player(player,"")
if inv then
local armorList=inv:get_list("armor")
assert(armorList)
for i=1,#armorList do
local stack=armorList[i]
if onGlobalStep(player,inv,stack) then
break
end
end
end
elseif industrialtest.mclAvailable then
local inv=player:get_inventory()
local stack=inv:get_stack("armor",1)
onGlobalStep(player,inv,stack)
end
end
end)

View File

@ -15,65 +15,45 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
local S=minetest.get_translator("industrialtest")
industrialtest.StaticBoots=table.copy(industrialtest.GearTool)
local image=(industrialtest.mtgAvailable and "industrialtest_static_boots.png" or "industrialtest_mcl_static_boots.png")
industrialtest.internal.unpackTableInto(industrialtest.StaticBoots,{
name="industrialtest:static_boots",
description=S("Static Boots"),
inventoryImage="industrialtest_static_boots_inv.png",
part="feet",
modelImage=image
})
local updateDelta=0
local playerPositions={}
local function onGlobalStep(player,inv,stack)
if stack:get_name()~="industrialtest:static_boots" then
return false
end
function industrialtest.StaticBoots.update(self,player,inv,itemstack,dtime)
local playerPos=player:get_pos()
playerPos.y=0
if not playerPositions[player:get_player_name()] then
playerPositions[player:get_player_name()]=playerPos
return true
return false
end
if vector.distance(playerPos,playerPositions[player:get_player_name()])<5 then
return true
return false
end
playerPositions[player:get_player_name()]=playerPos
local armorList=inv:get_list("armor")
for i=1,#armorList do
local meta=armorList[i]:get_meta()
for i,armorItemstack in ipairs(armorList) do
local meta=armorItemstack:get_meta()
if industrialtest.api.hasPowerStorage(meta) and not industrialtest.api.isFullyCharged(meta) then
industrialtest.api.addPowerToItem(armorList[i],1)
inv:set_stack("armor",i,armorList[i])
industrialtest.api.addPowerToItem(armorItemstack,1)
inv:set_stack("armor",i,armorItemstack)
break
end
end
return true
return false
end
if industrialtest.mtgAvailable then
armor:register_armor("industrialtest:static_boots",{
description=S("Static Boots"),
inventory_image="industrialtest_static_boots_inv.png",
groups={
armor_feet=1,
armor_heal=0
}
})
elseif industrialtest.mclAvailable then
minetest.register_tool("industrialtest:static_boots",{
description=S("Static Boots"),
inventory_image="industrialtest_static_boots_inv.png",
groups={
armor=1,
non_combat_armor=1,
armor_feet=1,
non_combat_feet=1
},
sounds={
_mcl_armor_equip="mcl_armor_equip_iron",
_mcl_armor_unequip="mcl_armor_unequip_iron"
},
on_place=mcl_armor.equip_on_use,
on_secondary_use=mcl_armor.equip_on_use,
_mcl_armor_element="feet",
_mcl_armor_texture="industrialtest_mcl_static_boots.png"
})
end
industrialtest.StaticBoots:register()
minetest.register_craft({
type="shaped",
output="industrialtest:static_boots",
@ -83,6 +63,7 @@ minetest.register_craft({
{"industrialtest:insulated_copper_cable","industrialtest:insulated_copper_cable","industrialtest:insulated_copper_cable"}
}
})
minetest.register_craft({
type="shaped",
output="industrialtest:static_boots",
@ -96,31 +77,3 @@ minetest.register_craft({
minetest.register_on_leaveplayer(function(player)
playerPositions[player:get_player_name()]=nil
end)
minetest.register_globalstep(function(dtime)
updateDelta=updateDelta+dtime
if updateDelta<industrialtest.updateDelay then
return
end
updateDelta=0
local players=minetest.get_connected_players()
for _,player in ipairs(players) do
if industrialtest.mtgAvailable then
local _,inv=armor:get_valid_player(player,"")
if inv then
local armorList=inv:get_list("armor")
assert(armorList)
for i=1,#armorList do
local stack=armorList[i]
if onGlobalStep(player,inv,stack) then
break
end
end
end
elseif industrialtest.mclAvailable then
local inv=player:get_inventory()
local stack=inv:get_stack("armor",5)
onGlobalStep(player,inv,stack)
end
end
end)

115
tools/tool.lua Normal file
View File

@ -0,0 +1,115 @@
-- 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 <http://www.gnu.org/licenses/>.
industrialtest.Tool=table.copy(industrialtest.Item)
industrialtest.internal.unpackTableInto(industrialtest.Tool,{
define={}
})
function industrialtest.Tool.use(self,itemstack,user,pointed)
-- dummy function
return false
end
function industrialtest.Tool.hitUse(self,itemstack,user,pointed)
-- Note: this method, when used, onUse must be set in define table
-- dummy function
return false
end
function industrialtest.Tool.onPlace(self,itemstack,user,pointed)
if self:use(itemstack,user,pointed) then
local meta=itemstack:get_meta()
if not meta:contains("industrialtest.uses") then
self:prepare(itemstack)
end
local uses=meta:get_int("industrialtest.uses")-1
if uses==0 then
itemstack:set_count(0)
minetest.sound_play({name="default_tool_breaks"},{
gain=1,
fade=0,
pitch=1
},true)
return true
end
meta:set_int("industrialtest.uses",uses)
itemstack:set_wear(65535-uses/self.uses*65535)
return true
end
return false
end
function industrialtest.Tool.onUse(self,itemstack,user,pointed)
if self:hitUse(itemstack,user,pointed) then
local meta=itemstack:get_meta()
if not meta:contains("industrialtest.uses") then
self:prepare(itemstack)
end
local uses=meta:get_int("industrialtest.uses")-1
if uses==0 then
itemstack:set_count(0)
minetest.sound_play({name="default_tool_breaks"},{
gain=1,
fade=0,
pitch=1
},true)
return true
end
meta:set_int("industrialtest.uses",uses)
itemstack:set_wear(65535-uses/self.uses*65535)
return true
end
return false
end
function industrialtest.Tool.prepare(self,itemstack)
local meta=itemstack:get_meta()
meta:set_int("industrialtest.uses",self.uses)
end
function industrialtest.Tool.createDefinitionTable(self)
local def=industrialtest.Item.createDefinitionTable(self)
def.tool_capabilities={
uses=self.uses
}
if self.define.onPlace then
def.on_place=function(itemstack,user,pointed)
if self:onPlace(itemstack,user,pointed) then
return itemstack
end
return nil
end
end
if self.define.onUse then
def.on_use=function(itemstack,user,pointed)
if self:onUse(itemstack,user,pointed) then
return itemstack
end
return nil
end
end
if industrialtest.mclAvailable then
def.groups={
tool=1
}
def._repair_material=self.repairMaterial
def._mcl_toollike_wield=true
end
return def
end

View File

@ -18,9 +18,10 @@ if industrialtest.mods.mclRubber then
return
end
local S=minetest.get_translator("industrialtest")
local function onTreetapUse(user,pointed)
if pointed.type~="node" or not user or not user:is_player() then
return false
end
local node=minetest.get_node_or_nil(pointed.under)
if not node then
return false
@ -36,34 +37,24 @@ local function onTreetapUse(user,pointed)
return false
end
local definition={
local S=minetest.get_translator("industrialtest")
industrialtest.Treetap=table.copy(industrialtest.Tool)
industrialtest.internal.unpackTableInto(industrialtest.Treetap,{
name="industrialtest:treetap",
define={onPlace=true},
description=S("Treetap"),
inventory_image="industrialtest_treetap.png",
tool_capabilities={
full_punch_interval=1,
uses=50
},
on_place=function(itemstack,user,pointed)
if pointed.type=="node" and user and user:is_player() and onTreetapUse(user,pointed) then
industrialtest.api.afterToolUse(itemstack)
return itemstack
inventoryImage="industrialtest_treetap.png",
uses=50,
flammable=2,
repairMaterial="group:wood"
})
function industrialtest.Treetap.use(self,itemstack,user,pointed)
return onTreetapUse(user,pointed)
end
return nil
end,
_industrialtest_tool=true
}
if industrialtest.mtgAvailable then
definition.groups={
flammable=2
}
elseif industrialtest.mclAvailable then
definition.groups={
tool=1
}
definition._repair_material="group:wood"
definition._mcl_toollike_wield=true
end
minetest.register_tool("industrialtest:treetap",definition)
industrialtest.Treetap:register()
minetest.register_craft({
type="shaped",
output="industrialtest:treetap",
@ -74,28 +65,26 @@ minetest.register_craft({
}
})
definition={
industrialtest.ElectricTreetap=table.copy(industrialtest.ElectricTool)
industrialtest.internal.unpackTableInto(industrialtest.ElectricTreetap,{
name="industrialtest:electric_treetap",
define={onPlace=true},
description=S("Electric Treetap"),
inventory_image="industrialtest_electric_treetap.png",
on_place=function(itemstack,user,pointed)
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.powerAmount")>=50 and user and user:is_player() and onTreetapUse(user,pointed) then
industrialtest.api.addPowerToItem(itemstack,-50)
return itemstack
inventoryImage="industrialtest_electric_treetap.png",
capacity=10000,
flow=industrialtest.api.lvPowerFlow
})
function industrialtest.ElectricTreetap.use(self,itemstack,user,pointed)
return onTreetapUse(user,pointed)
end
return nil
end,
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=10000,
_industrialtest_powerFlow=industrialtest.api.lvPowerFlow
}
if industrialtest.mclAvailable then
definition.groups={
tool=1
}
definition._mcl_toollike_wield=true
function industrialtest.ElectricTreetap.getOpPower(self,itemstack)
return 50
end
minetest.register_tool("industrialtest:electric_treetap",definition)
industrialtest.ElectricTreetap:register()
minetest.register_craft({
type="shapeless",
output="industrialtest:electric_treetap",

View File

@ -16,6 +16,9 @@
local S=minetest.get_translator("industrialtest")
local function onWrenchUse(user,pointed)
if pointed.type~="node" or not user or not user:is_player() then
return false
end
local node=minetest.get_node_or_nil(pointed.under)
if not node then
return false
@ -37,29 +40,22 @@ local function onWrenchUse(user,pointed)
return true
end
local definition={
industrialtest.Wrench=table.copy(industrialtest.Tool)
industrialtest.internal.unpackTableInto(industrialtest.Wrench,{
name="industrialtest:wrench",
define={onUse=true},
description=S("Wrench"),
inventory_image="industrialtest_wrench.png",
tool_capabilities={
full_punch_interval=1,
uses=200
},
on_use=function(itemstack,user,pointed)
if pointed.type=="node" and user and user:is_player() and onWrenchUse(user,pointed) then
industrialtest.api.afterToolUse(itemstack)
return itemstack
inventoryImage="industrialtest_wrench.png",
uses=200,
repairMaterial=industrialtest.elementKeys.bronzeIngot
})
function industrialtest.Wrench.hitUse(self,itemstack,user,pointed)
return onWrenchUse(user,pointed)
end
return nil
end,
_industrialtest_tool=true
}
if industrialtest.mclAvailable then
definition.groups={
tool=1
}
definition._mcl_toollike_wield=true
end
minetest.register_tool("industrialtest:wrench",definition)
industrialtest.Wrench:register()
minetest.register_craft({
type="shaped",
output="industrialtest:wrench",
@ -70,28 +66,26 @@ minetest.register_craft({
}
})
definition={
industrialtest.ElectricWrench=table.copy(industrialtest.ElectricTool)
industrialtest.internal.unpackTableInto(industrialtest.ElectricWrench,{
name="industrialtest:electric_wrench",
define={onUse=true},
description=S("Electric Wrench"),
inventory_image="industrialtest_electric_wrench.png",
on_use=function(itemstack,user,pointed)
local meta=itemstack:get_meta()
if meta:get_int("industrialtest.powerAmount")>=20 and user and user:is_player() and onWrenchUse(user,pointed) then
industrialtest.api.addPowerToItem(itemstack,-20)
return itemstack
inventoryImage="industrialtest_electric_wrench.png",
capacity=10000,
flow=industrialtest.api.lvPowerFlow
})
function industrialtest.ElectricWrench.getOpPower(self,itemstack)
return 50
end
return nil
end,
_industrialtest_powerStorage=true,
_industrialtest_powerCapacity=10000,
_industrialtest_powerFlow=industrialtest.api.lvPowerFlow
}
if industrialtest.mclAvailable then
definition.groups={
tool=1
}
definition._mcl_toollike_wield=true
function industrialtest.ElectricWrench.hitUse(self,itemstack,user,pointed)
return onWrenchUse(user,pointed)
end
minetest.register_tool("industrialtest:electric_wrench",definition)
industrialtest.ElectricWrench:register()
minetest.register_craft({
type="shapeless",
output="industrialtest:electric_wrench",

View File

@ -16,12 +16,74 @@
local S=minetest.get_translator("industrialtest")
industrialtest.internal.applyUpgrade=function(pos,meta,stack)
local def=minetest.registered_items[stack:get_name()]
if def.groups._industrialtest_upgradeSpeed then
industrialtest.Upgrade={}
function industrialtest.Upgrade.createDefinitionTable(self)
local def={
description=self.description,
inventory_image=self.inventoryImage,
groups={
_industrialtest_machineUpgrade=1
},
_industrialtest_self=self
}
return def
end
function industrialtest.Upgrade.register(self)
local def=self:createDefinitionTable()
minetest.register_craftitem(self.name,def)
end
function industrialtest.Upgrade.apply(self,pos)
-- dummy function
end
function industrialtest.Upgrade.remove(self,pos)
-- dummy function
end
industrialtest.OverclockerUpgrade=table.copy(industrialtest.Upgrade)
industrialtest.internal.unpackTableInto(industrialtest.OverclockerUpgrade,{
name="industrialtest:overclocker_upgrade",
description=S("Overclocker Upgrade"),
inventoryImage="industrialtest_overclocker_upgrade.png",
_speed=1
})
function industrialtest.OverclockerUpgrade.apply(self,pos)
local meta=minetest.get_meta(pos)
local speed=industrialtest.api.getMachineSpeed(meta)
meta:set_int("industrialtest.speed",math.min(4,speed+def.groups._industrialtest_upgradeSpeed))
elseif def.groups._industrialtest_upgradeTransformer then
meta:set_int("industrialtest.speed",math.min(4,speed+self._speed))
end
function industrialtest.OverclockerUpgrade.remove(self,pos)
local meta=minetest.get_meta(pos)
local speed=industrialtest.api.getMachineSpeed(meta)
meta:set_int("industrialtest.speed",math.max(1,speed-self._speed))
end
industrialtest.OverclockerUpgrade:register()
minetest.register_craft({
type="shaped",
output="industrialtest:overclocker_upgrade",
recipe={
{"industrialtest:coolant_cell","industrialtest:coolant_cell","industrialtest:coolant_cell"},
{"industrialtest:insulated_copper_cable","industrialtest:electronic_circuit","industrialtest:insulated_copper_cable"}
}
})
industrialtest.TransformerUpgrade=table.copy(industrialtest.Upgrade)
industrialtest.internal.unpackTableInto(industrialtest.TransformerUpgrade,{
name="industrialtest:transformer_upgrade",
description=S("Transformer Upgrade"),
inventoryImage="industrialtest_transformer_upgrade.png"
})
function industrialtest.TransformerUpgrade.apply(self,pos)
local meta=minetest.get_meta(pos)
local flows={
industrialtest.api.lvPowerFlow,
industrialtest.api.mvPowerFlow,
@ -44,27 +106,10 @@ industrialtest.internal.applyUpgrade=function(pos,meta,stack)
industrialtest.api.createNetworkMapForNode(network)
end
end
elseif def.groups._industrialtest_upgradePowerStorage then
meta:set_int("industrialtest.powerCapacity",meta:get_int("industrialtest.powerCapacity")+10000)
local nodeDef=minetest.registered_nodes[minetest.get_node(pos).name]
if nodeDef._industrialtest_updateFormspec then
nodeDef._industrialtest_updateFormspec(pos)
end
local networks=industrialtest.api.isAttachedToNetwork(meta)
if networks then
for _,network in ipairs(networks) do
minetest.get_node_timer(network):start(industrialtest.updateDelay)
end
end
end
end
industrialtest.internal.removeUpgrade=function(pos,meta,stack)
local def=minetest.registered_items[stack:get_name()]
if def.groups._industrialtest_upgradeSpeed and meta:contains("industrialtest.speed") then
local speed=meta:get_int("industrialtest.speed")
meta:set_int("industrialtest.speed",math.max(1,speed-def.groups._industrialtest_upgradeSpeed))
elseif def.groups._industrialtest_upgradeTransformer then
function industrialtest.TransformerUpgrade.remove(self,pos)
local meta=minetest.get_meta(pos)
local flows={
industrialtest.api.lvPowerFlow,
industrialtest.api.mvPowerFlow,
@ -85,51 +130,13 @@ industrialtest.internal.removeUpgrade=function(pos,meta,stack)
local networks=industrialtest.api.isAttachedToNetwork(meta)
if networks then
for _,network in ipairs(networks) do
minetest.get_node_timer(network):start(industrialtest.updateDelay)
end
end
elseif def.groups._industrialtest_upgradePowerStorage then
meta:set_int("industrialtest.powerCapacity",meta:get_int("industrialtest.powerCapacity")-10000)
meta:set_int("industrialtest.powerAmount",math.min(meta:get_int("industrialtest.powerAmount"),meta:get_int("industrialtest.powerCapacity")))
local nodeDef=minetest.registered_nodes[minetest.get_node(pos).name]
if nodeDef._industrialtest_updateFormspec then
nodeDef._industrialtest_updateFormspec(pos)
industrialtest.api.createNetworkMapForNode(network)
end
end
end
local function registerMachineUpgrade(config)
minetest.register_craftitem("industrialtest:"..config.name,{
description=config.displayName,
inventory_image="industrialtest_"..config.name..".png",
groups={
_industrialtest_machineUpgrade=1,
_industrialtest_upgradeSpeed=config.speed or nil,
_industrialtest_upgradeTransformer=config.transformer or nil,
_industrialtest_upgradePowerStorage=config.powerStorage or nil,
}
})
end
industrialtest.TransformerUpgrade:register()
registerMachineUpgrade({
name="overclocker_upgrade",
displayName=S("Overclocker Upgrade"),
speed=1
})
minetest.register_craft({
type="shaped",
output="industrialtest:overclocker_upgrade",
recipe={
{"industrialtest:coolant_cell","industrialtest:coolant_cell","industrialtest:coolant_cell"},
{"industrialtest:insulated_copper_cable","industrialtest:electronic_circuit","industrialtest:insulated_copper_cable"}
}
})
registerMachineUpgrade({
name="transformer_upgrade",
displayName=S("Transformer Upgrade"),
transformer=1
})
minetest.register_craft({
type="shaped",
output="industrialtest:transformer_upgrade",
@ -140,11 +147,40 @@ minetest.register_craft({
}
})
registerMachineUpgrade({
name="power_storage_upgrade",
displayName=S("Power Storage Upgrade"),
powerStorage=1
industrialtest.PowerStorageUpgrade=table.copy(industrialtest.Upgrade)
industrialtest.internal.unpackTableInto(industrialtest.PowerStorageUpgrade,{
name="industrialtest:power_storage_upgrade",
description=S("Power Storage Upgrade"),
inventoryImage="industrialtest_power_storage_upgrade.png",
_storage=10000
})
function industrialtest.PowerStorageUpgrade.apply(self,pos)
local meta=minetest.get_meta(pos)
meta:set_int("industrialtest.powerCapacity",meta:get_int("industrialtest.powerCapacity")+self._storage)
local node=minetest.get_node(pos)
local def=minetest.registered_nodes[node.name]
if def._industrialtest_self then
def._industrialtest_self:updateFormspec(pos)
if def._industrialtest_self.requestPower then
def._industrialtest_self:requestPower(pos)
end
end
end
function industrialtest.PowerStorageUpgrade.remove(self,pos)
local meta=minetest.get_meta(pos)
meta:set_int("industrialtest.powerCapacity",meta:get_int("industrialtest.powerCapacity")-self._storage)
meta:set_int("industrialtest.powerAmount",math.min(meta:get_int("industrialtest.powerAmount"),meta:get_int("industrialtest.powerCapacity")))
local node=minetest.get_node(pos)
local def=minetest.registered_nodes[node.name]
if def._industrialtest_self then
def._industrialtest_self:updateFormspec(pos)
end
end
industrialtest.PowerStorageUpgrade:register()
minetest.register_craft({
type="shaped",
output="industrialtest:power_storage_upgrade",

View File

@ -19,30 +19,39 @@ local S=minetest.get_translator("industrialtest")
local powerStorageInspectorContext={}
local function inspectNode(pos,playerName)
local meta=minetest.get_meta(pos)
local sides={"X-","X+","Y-","Y+","Z-","Z+"}
local powerCapacity=meta:get_int("industrialtest.powerCapacity")
local powerFlow=meta:get_int("industrialtest.powerFlow")
local powerAmount=meta:get_int("industrialtest.powerAmount")
local powerIOConfig=meta:get_string("industrialtest.ioConfig")
local powerIOConfig
if industrialtest.api.isExtendedIoConfig(meta) then
powerIOConfig="\n"
local ioConfig=minetest.deserialize(meta:get_string("industrialtest.ioConfig"))
for i,config in ipairs(ioConfig) do
powerIOConfig=powerIOConfig..sides[i].." "..config.mode.." "..config.flow.."\n"
end
else
powerIOConfig=meta:get_string("industrialtest.ioConfig")
end
local formspec={
"formspec_version[4]",
"size[8,8]",
"size[15,15]",
"label[0.5,0.5;"..S("Power Storage Inspector").."]",
"label[0.5,1.5;"..S("Power Capacity: @1",powerCapacity).."]",
"label[0.5,1.9;"..S("Power Flow: @1",powerFlow).."]",
"label[0.5,2.3;"..S("Power Amount: @1",powerAmount).."]",
"label[0.5,2.7;"..S("Power IO Config: @1",powerIOConfig).."]",
"field[0.5,3.7;2,0.5;powerCapacity;"..S("Power Capacity")..";"..powerCapacity.."]",
"field[0.5,4.5;2,0.5;powerFlow;"..S("Power Flow")..";"..powerFlow.."]",
"field[0.5,5.4;2,0.5;powerAmount;"..S("Power Amount")..";"..powerAmount.."]",
"field[0.5,6.2;2,0.5;powerIOConfig;"..S("Power IO Config")..";"..powerIOConfig.."]",
"button[0.5,6.8;2,0.5;update;"..S("Update").."]",
"field[0.5,7.0;2,0.5;powerCapacity;"..S("Power Capacity")..";"..powerCapacity.."]",
"field[0.5,8.0;2,0.5;powerFlow;"..S("Power Flow")..";"..powerFlow.."]",
"field[0.5,9.0;2,0.5;powerAmount;"..S("Power Amount")..";"..powerAmount.."]",
"field[0.5,10.0;2,0.5;powerIOConfig;"..S("Power IO Config")..";"..meta:get_string("industrialtest.ioConfig").."]",
"button[0.5,11.0;2,0.5;update;"..S("Update").."]",
"label[4.2,2.25;"..S("Connections:").."]"
}
local connections=industrialtest.api.getConnections(pos)
local sides={"X-","X+","Y-","Y+","Z-","Z+"}
local sideString=""
for _,value in ipairs(connections) do
sideString=sideString.."("..value.x..", "..value.y..", "..value.z..")\n"
for i,value in ipairs(connections) do
sideString=sideString..sides[i].." ("..value.x..", "..value.y..", "..value.z..")\n"
end
table.insert(formspec,"label[4.2,2.65;"..sideString.."]")
powerStorageInspectorContext[playerName]=pos
@ -71,7 +80,11 @@ minetest.register_on_player_receive_fields(function(player,formname,fields)
meta:set_int("industrialtest.powerCapacity",tonumber(fields.powerCapacity))
meta:set_int("industrialtest.powerFlow",tonumber(fields.powerFlow))
meta:set_int("industrialtest.powerAmount",tonumber(fields.powerAmount))
if industrialtest.api.isExtendedIoConfig(meta) then
meta:set_string("industrialtest.powerIOConfig",minetest.serialize(fields.powerIOConfig))
else
meta:set_string("industrialtest.powerIOConfig",fields.powerIOConfig)
end
local def=minetest.registered_nodes[minetest.get_node(context).name]
if def and def._industrialtest_updateFormspec then
def._industrialtest_updateFormspec(context)

View File

@ -15,14 +15,38 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
minetest.register_craft({
type="shapeless",
output=industrialtest.elementKeys.stone.." 16",
recipe={"industrialtest:uu_matter"}
type="shaped",
output=industrialtest.elementKeys.wood.." 48",
recipe={
{"","industrialtest:uu_matter",""},
{"","",""},
{"","",""}
}
})
minetest.register_craft({
type="shaped",
output=industrialtest.elementKeys.grassBlock.." 16",
output=industrialtest.elementKeys.stone.." 48",
recipe={
{"","",""},
{"","industrialtest:uu_matter",""},
{"","",""}
}
})
minetest.register_craft({
type="shaped",
output=industrialtest.elementKeys.snowBlock.." 48",
recipe={
{"industrialtest:uu_matter","","industrialtest:uu_matter"},
{"","",""},
{"","",""}
}
})
minetest.register_craft({
type="shaped",
output=industrialtest.elementKeys.grassBlock.." 48",
recipe={
{"industrialtest:uu_matter"},
{"industrialtest:uu_matter"}
@ -31,11 +55,10 @@ minetest.register_craft({
minetest.register_craft({
type="shaped",
output=industrialtest.elementKeys.wood.." 16",
output=industrialtest.elementKeys.obsidian.." 16",
recipe={
{"","industrialtest:uu_matter",""},
{"","",""},
{"industrialtest:uu_matter","",""}
{"industrialtest:uu_matter"},
{"industrialtest:uu_matter"}
}
})
@ -58,7 +81,57 @@ minetest.register_craft({
}
})
minetest.register_craft({
type="shaped",
output=industrialtest.elementKeys.cactus.." 48",
recipe={
{"","industrialtest:uu_matter",""},
{"industrialtest:uu_matter","industrialtest:uu_matter","industrialtest:uu_matter"},
{"industrialtest:uu_matter","","industrialtest:uu_matter"}
}
})
minetest.register_craft({
type="shaped",
output=industrialtest.elementKeys.flint.." 32",
recipe={
{"","industrialtest:uu_matter",""},
{"industrialtest:uu_matter","industrialtest:uu_matter",""},
{"industrialtest:uu_matter","industrialtest:uu_matter",""}
}
})
minetest.register_craft({
type="shaped",
output=industrialtest.elementKeys.whiteWool.." 12",
recipe={
{"industrialtest:uu_matter","","industrialtest:uu_matter"},
{"","",""},
{"","industrialtest:uu_matter",""}
}
})
minetest.register_craft({
type="shaped",
output=industrialtest.elementKeys.sugarCane.." 48",
recipe={
{"industrialtest:uu_matter","","industrialtest:uu_matter"},
{"industrialtest:uu_matter","","industrialtest:uu_matter"},
{"industrialtest:uu_matter","","industrialtest:uu_matter"}
}
})
if industrialtest.mclAvailable then
minetest.register_craft({
type="shaped",
output="mcl_core:vine 24",
recipe={
{"industrialtest:uu_matter","",""},
{"industrialtest:uu_matter","",""},
{"industrialtest:uu_matter","",""}
}
})
minetest.register_craft({
type="shaped",
output="mcl_core:stonebrickcarved 48",