45 Commits

Author SHA1 Message Date
4a5a22a3e3 LV LED: Replace silver wire with empty spool on craft 2025-06-14 21:31:00 +02:00
85e342c08c Sonic Screwdriver: Support every paramtype2 (#662) 2025-05-14 19:52:22 +02:00
0ff7cb769b Fix shading on CNC shape models
Luanti 5.11 showed a lot of flaws in the shading of the CNC models, some
of which were previously obscured. Fix the models so that smooth shading
is applied where appropriate and sharp/flat shading where appropriate.
The modified files have also been run through ExeVirus' CompressObj.
2025-03-01 10:27:59 +01:00
3bece9cec5 Fix incorrect recipe registration for craftguide and i3 2024-12-16 20:46:14 +01:00
59643c45d4 Chainsaw: Chat message for 'aborted by safe cut'
This provides a feedback to the player.
2024-12-07 22:15:43 +01:00
b268e3d526 Fix machines connected to multiple networks (#655)
Machines sometimes were be a part of multiple networks and generated power for each. This is fixed by checking if the machine is already part of an other network before assigning it to the current network.
2024-11-29 18:58:51 +01:00
87e512ff24 Fix power monitor instability (#654)
This fixes the power monitor instability where it was switching between having and not having network infotext. The cause was that the power monitor is LV MV and HV machine at the same time, and each tier has a countdown. If any of these countdowns were 0 it treated the machine as having no network. This was changed so that it only treats a machine as having no network if it is timed out in all tiers that it is a part of.
2024-11-22 21:19:49 +01:00
18df2813a0 Comment print statements in battery_box.lua (#650) 2024-09-06 19:10:04 +02:00
221fc1376e technic_cnc: use programs definition to generate formspec (#647)
This deprecates the variables onesize_products and twosize_products by using a shared definition table.
With these changes, it should be easier to add new programs in the future.

New feature: Tooltips are added to all programs. (only applies to newly placed nodes)
2024-08-10 10:50:51 +02:00
9f373d6528 technic_cnc: Add group 'cracky'
Fixes a regression from ba2bdf836 where stone-like nodes could no longer be dug.
New sanity check to avoid such issues in the future.
2024-08-03 08:25:13 +02:00
6731db14e5 Add compressor recipes for nether racks (#644) 2024-07-07 18:53:15 +02:00
a9079c49e0 Expose technic.get/set_charge functions (#645) 2024-07-07 18:45:03 +02:00
f80372a0f8 Frames: Fix error in node placement callback execution 2024-05-18 18:05:44 +02:00
80dee96dbe Add grinding recipe for nether lump + refactor grinder recipes (#638)
Maintenance:

* Sort dependency-based entries alphabetically
* Refactor dust registration

Features:

* Add grinding recipe for nether lump and ingot + image for nether dust
2024-05-06 17:33:22 +02:00
d65c4aadd2 Add grinder crafting recipe from everness desert stone (#637)
Add two alternative grinder crafting recipes with the two everness desert stones
2024-05-06 17:31:13 +02:00
98675a2ae9 Add compressor recipes for nether brick and lump (#639)
Another addition with nether, similar to the previous one, just this time for compressor.

Clears nether's default recipes for compressed nether brick and nether lump, using the compressor instead for these tasks.
2024-04-30 17:44:51 +02:00
ba2bdf8368 technic_cnc: Use client-side translation API (#636) 2024-04-28 18:41:52 +02:00
d5ff69d1d9 Add Everness sandstone compressor recipes (#634) 2024-03-25 19:45:57 +01:00
f47da0c045 Add grinding for pyrite from Everness mod (#633)
Add recipe for grinding pyrite lump from everness mod into pyrite dust if everness mod is present (also includes images for pyrite dust).
2024-03-08 18:44:13 +01:00
a08ba2bb93 Get rid of deprecated metadata (#628)
The deprecated metadata gets converted to a proper ItemStackMetaRef.
All keys stay the same except for:
- Cans that use `can_level` now, since they didn't store a serialized table in the metadata before.
- `charge` which is now `technic:charge`, since any item (also from other mods) may have a technic charge which can cause compatibility problems.

Backwards compatibility is kept but going back to older `technic` versions might result in misbehaving circuits.
2024-01-22 18:27:54 +01:00
410e341da5 HV Reactor: Improve formspec layout 2024-01-09 21:51:08 +01:00
5826c2feaa Fix outdated dependency links (#627) 2024-01-06 12:26:20 +01:00
b221d69717 Remove duplicated textures
Now the ingot textures provided by commit 83e9cab3 are loaded
2023-12-19 18:59:46 +01:00
a296446da1 Add granite brick node (#593) 2023-12-19 18:25:45 +01:00
49d4105a2b Quarry: revert startpos+1 air-like node check
Quarries are also deployed in entirely solid underground, where
it is expected that the quarry produces a new shaft from scratch.
2023-10-01 10:47:59 +02:00
fda8a3d042 Quarry: Allow digging in different airlike environments
This offloads the digging check to a separate function for better code separation.
2023-09-23 13:25:11 +02:00
dfcf64c1d0 Chainsaw: new setting to disable safe cutting
Some trees might generate with param2 != 0, which makes the
chainsaw appear blunt/useless. This safety feature is now
customizable.
2023-08-26 10:57:05 +02:00
0921c326a8 Chainsaw: fix occasional error on startup
This also tweaks the cost function to make the chainsaw a bit less powerful.
2023-08-03 21:28:41 +02:00
9b7c44b453 Wrench: Fix node registration from other mods 2023-01-29 13:11:37 +01:00
86e083c409 Document a few derived textures
Thanks to cx384 for providing this input
2023-01-11 20:43:06 +01:00
21e044478e Fix battery box charging issues caused by out of sync functions
This code should be merged in the future to avoid such issues.
2022-11-26 23:25:33 +01:00
521c0b74bb Fix battery box charging on Windows 2022-11-24 21:49:20 +01:00
aad1b2875a Add Japanese translation (#613) 2022-11-17 19:59:39 +01:00
66e20a9231 Add register_cable_tier API function (#612) 2022-11-04 19:23:44 +01:00
705961e2fe Supply converter: Charge batteries again 2022-11-01 20:27:26 +01:00
6a9dfec36f Batteries: Workaround to fix discharge (#609)
The network traversal code does still not handle connecting sides,
but at least finite power is no more.
2022-10-29 21:36:48 +02:00
d4609f23f2 Chests: Use prepend styling and re-order elements (#608) 2022-10-29 21:36:33 +02:00
091bb2406d Chainsaw: Add certain dftrees "fruit"-like nodes 2022-10-26 19:17:40 +02:00
c40189eabf Export technic_music_player_top.png to PNG, run optipng 2022-10-25 18:17:45 +02:00
f61bb82bd1 add recipes to grind all sand types into stone dust
idea from https://github.com/minetest-mods/technic/issues/573
2022-10-25 18:08:28 +02:00
7d39136764 Chainsaw: Partial rewrite, various improvements (#607)
Introduces protection checks for the entire tree
More efficient node digging (VoxelManip)
Improved drop handling using detached inventories for correct stack sizes

Approximate speed-up of approx. 7x compared to the previous code for a giant sequoia.
2022-10-25 18:03:51 +02:00
4775d98fb7 Unify and simplify LED/Lamp node definition 2022-10-20 20:08:56 +02:00
d623715d94 Add LV led and lamp 2022-10-20 18:28:45 +02:00
718a5beda1 Supply converter: demany only the needed power (#577)
Supply converter demands only the needed power to satisfy the demand on the output network. It can still be too much if the output network has other power sources, because supply is not taken in account.

This surplus of energy can be used to charge batteries.
2022-10-20 17:56:10 +02:00
fa39b24ed5 Document lead and sulfur 2022-10-19 21:51:09 +02:00
174 changed files with 2271 additions and 1709 deletions

View File

@ -15,10 +15,10 @@ world. A few notable features:
* Minetest 5.0.0 or newer
* [Minetest Game](https://github.com/minetest/minetest_game/)
* [mesecons](https://github.com/minetest-mods/mesecons) -> signalling events
* [pipeworks](https://gitlab.com/VanessaE/pipeworks/) -> automation of item transport
* [pipeworks](https://github.com/mt-mods/pipeworks) -> automation of item transport
* [moreores](https://github.com/minetest-mods/moreores/) -> additional ores
* [basic_materials](https://gitlab.com/VanessaE/basic_materials) -> basic craft items
* Supports [moretrees](https://gitlab.com/VanessaE/moretrees) -> rubber trees
* [basic_materials](https://github.com/mt-mods/basic_materials) -> basic craft items
* Supports [moretrees](https://github.com/mt-mods/moretrees) -> rubber trees
* Consult `depends.txt` or `mod.conf` of each mod for further dependency information.

9
concrete/locale/ja.txt Normal file
View File

@ -0,0 +1,9 @@
# technic_concrete japanese translation
# technic_concreteの日本語への翻訳
# by damiemk
Rebar = 鉄筋
Concrete Block = コンクリートのブロック
Blast-resistant Concrete Block = 耐爆性コンクリートのブロック
Concrete Post Platform = コンクリートのプラットフォーム
Concrete Post = コンクリートポスト

View File

@ -27,6 +27,12 @@ if minetest.get_modpath("moreblocks") then
tiles={"technic_granite.png"},
})
stairsplus:register_all("technic", "granite_bricks", "technic:granite_bricks", {
description=S("Granite Bricks"),
groups={cracky=1, not_in_creative_inventory=1},
tiles={"technic_granite_bricks.png"},
})
stairsplus:register_all("technic", "concrete", "technic:concrete", {
description=S("Concrete"),
groups={cracky=3, not_in_creative_inventory=1},

8
extranodes/locale/ja.txt Normal file
View File

@ -0,0 +1,8 @@
# technic_extranodes japanese translation
# technic_extranodesの日本語への翻訳
# by damiemk
Marble = 大理石
Marble Bricks = 大理石のレンガ
Granite = 花崗岩
Concrete = コンクリート

104
manual.md
View File

@ -34,6 +34,11 @@ Note ¹: *These ores are provided by Minetest Game. See [Ores](https://wiki.mine
Note ²: *These ores are provided by moreores. TODO: Add reference link*
#### Chromium
Use: stainless steel
Generated below: -100m, more commonly below -200m
#### Coal ¹
Use: Fuel, alloy as carbon
@ -41,33 +46,61 @@ Burning coal is a way to generate electrical power. Coal is also used,
usually in dust form, as an ingredient in alloying recipes, wherever
elemental carbon is required.
#### Iron ¹
Use: multiple, mainly for alloys with carbon (coal).
#### Copper ¹
Copper is a common metal, used either on its own for its electrical
conductivity, or as the base component of alloys.
Although common, it is very heavily used, and most of the time it will
be the material that most limits your activity.
#### Diamond ¹
Use: mainly for cutting machines
Diamond is a precious gemstone. It is used moderately, mainly for reasons
connected to its extreme hardness.
#### Gold ¹
Use: various
Generated below: -64m, more commonly below -256m
Gold is a precious metal. It is most notably used in electrical items due to
its combination of good conductivity and corrosion resistance.
#### Iron ¹
Use: multiple, mainly for alloys with carbon (coal).
#### Lead
Use: batteries, HV nuclear reactor layout
Generated below: 16m, more common below -128m
#### Mese ¹
Use: various
Mese is a precious gemstone, and unlike diamond it is entirely fictional.
It is used in small quantities, wherever some magic needs to be imparted.
#### Mithril ²
Use: chests
Generated below: -512m, evenly common
Mithril is a fictional ore, being derived from J. R. R. Tolkien's
Middle-Earth setting. It is little used.
#### Silver ²
Use: conductors
Generated below: -2m, evenly common
Silver is a semi-precious metal and is the best conductor of all the pure elements.
#### Tin ¹
Use: batteries, bronze
Tin is a common metal but is used rarely. Its abundance is well in excess
of its usage, so you will usually have a surplus of it.
#### Zinc
Use: brass
Generated below: 2m, more commonly below -32m
Zinc only has a few uses but is a common metal.
#### Chromium
Use: stainless steel
Generated below: -100m, more commonly below -200m
#### Uranium
Use: nuclear reactor fuel
@ -79,40 +112,13 @@ shielding materials available.
Keep a safety distance of a meter to avoid being harmed by radiation.
#### Silver ²
Use: conductors
#### Zinc
Use: brass
Generated below: -2m, evenly common
Generated below: 2m, more commonly below -32m
Silver is a semi-precious metal and is the best conductor of all the pure elements.
Zinc only has a few uses but is a common metal.
#### Gold ¹
Use: various
Generated below: -64m, more commonly below -256m
Gold is a precious metal. It is most notably used in electrical items due to
its combination of good conductivity and corrosion resistance.
#### Mithril ²
Use: chests
Generated below: -512m, evenly common
Mithril is a fictional ore, being derived from J. R. R. Tolkien's
Middle-Earth setting. It is little used.
#### Mese ¹
Use: various
Mese is a precious gemstone, and unlike diamond it is entirely fictional.
It is used in small quantities, wherever some magic needs to be imparted.
#### Diamond ¹
Use: mainly for cutting machines
Diamond is a precious gemstone. It is used moderately, mainly for reasons
connected to its extreme hardness.
### 2.2 Rocks
@ -136,6 +142,12 @@ Granite is found in dense clusters and is much harder to dig than standard
stone. It has mainly decorative use, but also appears in a couple of
machine recipes.
#### Sulfur
Uses: battery box
Sulur is generated around some lava patches (caves).
### 2.3 Rubber
Rubber is a biologically-derived material that has industrial uses due
to its electrical resistivity and its impermeability. In technic, it

View File

@ -1 +1,3 @@
name = technic
description = technic
min_minetest_version = 5.0

9
settingtypes.txt Normal file
View File

@ -0,0 +1,9 @@
# Safety feature for the chainsaw tool aimed to prevent cutting structures
# built by players.
#
# Trunk nodes generated by mapgen have a rotation of '0' whereas manually
# placed trunks usually have another value. However, some mods might generate
# trees with rotation != 0, which renders the chainsaw useless on them.
#
# Disabling this feature will sacrifice safety for convenience.
technic_safe_chainsaw (Chainsaw safety feature) bool true

View File

@ -1,14 +1,16 @@
Technic
=======
# Technic (main mod)
License
-------
## License
### Code
Copyright (C) 2012-2014 Maciej Kasatkin (RealBadAngel)
Technic chests code is licensed under the GNU LGPLv2+.
Texture licenses:
### Textures
BlockMen modified by Zefram (CC BY-SA 3.0):
* technic_chernobylite_block.png
@ -24,15 +26,29 @@ sdzen (Elise Staudter) (CC BY-SA 3.0):
leftshift (CC BY-SA 3.0):
* technic_river_water_can.png
Neuromancer vis Minetest Game (CC BY-SA 3.0)
* `technic_*_electric_furnace_*.png` (derived)
[LB Photo Realism Reload](https://www.curseforge.com/minecraft/texture-packs/lb-photo-realism-reload) (CC 0)
* `technic_geothermal_*.png` (derived)
* `technic_water_mill_*.png` (derived)
* `technic_*_alloy_furnace_*.png` (derived)
* `technic_*_compressor_*.png` (derived)
* `technic_*_grinder_*.png` (derived)
RealBadAngel: (WTFPL)
* Everything else.
CC BY-SA 3.0: <http://creativecommons.org/licenses/by-sa/3.0/>
Sound licenses:
### Sounds
veikk0 (Veikko Mäkelä) (CC BY-SA 4.0):
* technic_hv_nuclear_reactor_siren_danger_loop.ogg
* Derived from "Nuclear alarm.wav" by Freesound.org user rene___ from <https://freesound.org/people/rene___/sounds/56778/>. Originally licensed under CC0 1.0 <https://creativecommons.org/publicdomain/zero/1.0/>
CC BY-SA 4.0: <https://creativecommons.org/licenses/by-sa/4.0/>
### References
CC BY-SA 3.0: http://creativecommons.org/licenses/by-sa/3.0/
CC BY-SA 4.0: https://creativecommons.org/licenses/by-sa/4.0/

View File

@ -35,6 +35,10 @@ Available functions:
* `technic.is_tier_cable(nodename, tier)`
* Tells whether the node `nodename` is the cable of the tier `tier`.
* Short version of `technic.get_cable_tier(nodename) == tier`
* `technic.register_cable_tier(nodename, tier)`
* Register user defined cable to list of known tier cables.
* `nodename`: string, name of the node
* `tier`: string, tier name
## Machines
@ -156,6 +160,11 @@ Unsorted functions:
* If `technic.power_tools[itemstack:get_name()]` is `nil` (or `false`), this
function does nothing, else that value is the maximum charge.
* The itemstack metadata is changed to contain the charge.
* `technic.get_charge(itemstack)`
* Returns the charge and max charge of the given itemstack.
* If the itemstack is not an RE chargeable item, both return values will be zero.
* `technic.set_charge(itemstack, charge)`
* Modifies the charge of the given itemstack.
### Node-specific
* `technic.get_or_load_node(pos)`

View File

@ -65,15 +65,26 @@ function technic.swap_node(pos, name)
end
--- Returns the meta of an item
-- Gets overridden when legacy.lua is loaded
function technic.get_stack_meta(itemstack)
return itemstack:get_meta()
end
--- Same as technic.get_stack_meta for cans
function technic.get_stack_meta_cans(itemstack)
return itemstack:get_meta()
end
--- Fully charge RE chargeable item.
-- Must be defined early to reference in item definitions.
function technic.refill_RE_charge(stack)
local max_charge = technic.power_tools[stack:get_name()]
if not max_charge then return stack end
local meta = technic.get_stack_meta(stack)
meta:set_int("technic:charge", max_charge)
technic.set_RE_wear(stack, max_charge, max_charge)
local meta = minetest.deserialize(stack:get_metadata()) or {}
meta.charge = max_charge
stack:set_metadata(minetest.serialize(meta))
return stack
end

View File

@ -39,3 +39,40 @@ for i = 0, 64 do
minetest.register_alias("technic:lv_cable"..i, "technic:lv_cable")
end
-- Item meta
-- Meta keys that have changed
technic.legacy_meta_keys = {
["charge"] = "technic:charge",
}
-- Converts legacy itemstack metadata string to itemstack meta and returns the ItemStackMetaRef
function technic.get_stack_meta(itemstack)
local meta = itemstack:get_meta()
local legacy_string = meta:get("") -- Get deprecated metadata
if legacy_string then
local legacy_table = minetest.deserialize(legacy_string)
if legacy_table then
local table = meta:to_table()
for k, v in pairs(legacy_table) do
table.fields[technic.legacy_meta_keys[k] or k] = v
end
meta:from_table(table)
end
meta:set_string("", "") -- Remove deprecated metadata
end
return meta
end
-- Same as technic.get_stack_meta for cans.
-- (Cans didn't store a serialized table in the legacy metadata string, but just a number.)
function technic.get_stack_meta_cans(itemstack)
local meta = itemstack:get_meta()
local legacy_string = meta:get("") -- Get deprecated metadata
if legacy_string then
meta:set_string("can_level", legacy_string)
meta:set_string("", "") -- Remove deprecated metadata
return meta
end
return meta
end

View File

@ -31,24 +31,26 @@ minetest.register_craft({
})
local function make_reactor_formspec(meta)
local f = "size[8,9]"..
"label[0,0;"..S("Nuclear Reactor Rod Compartment").."]"..
"list[current_name;src;2,1;3,2;]"..
"list[current_player;main;0,5;8,4;]"..
"listring[]"..
"button[5.5,1.5;2,1;start;Start]"..
"checkbox[5.5,2.5;autostart;automatic Start;"..meta:get_string("autostart").."]"
local f =
"formspec_version[4]"..
"size[10.75,10.75]"..
"label[0.2,0.4;"..S("Nuclear Reactor Rod Compartment").."]"..
"list[current_name;src;1.5,1;3,2;]"..
"list[current_player;main;0.5,5.5;8,4;]"..
"listring[]"..
"button[5.7,1;2,1;start;Start]"..
"checkbox[5.7,2.75;autostart;automatic Start;"..meta:get_string("autostart").."]"
if not digiline_remote_path then
return f
end
local digiline_enabled = meta:get_string("enable_digiline")
f = f.."checkbox[0.5,2.8;enable_digiline;Enable Digiline;"..digiline_enabled.."]"
f = f.."checkbox[1.5,3.75;enable_digiline;Enable Digiline channel;"..digiline_enabled.."]"
if digiline_enabled ~= "true" then
return f
end
return f..
"button_exit[4.6,3.69;2,1;save;Save]"..
"field[1,4;4,1;remote_channel;Digiline Remote Channel;${remote_channel}]"
"field[2,4.2;4.25,1;remote_channel;;${remote_channel}]" ..
"button_exit[6.5,4.2;2,1;save;Save]"
end
local SS_OFF = 0
@ -140,8 +142,11 @@ of a lead layer it will be converted to a lead layer.
--]]
local function reactor_structure_badness(pos)
local vm = VoxelManip()
-- Blast-resistant Concrete Block layer outer positions
local pos1 = vector.subtract(pos, 3)
local pos2 = vector.add(pos, 3)
local MinEdge, MaxEdge = vm:read_from_map(pos1, pos2)
local data = vm:get_data()
local area = VoxelArea:new({MinEdge=MinEdge, MaxEdge=MaxEdge})
@ -157,16 +162,19 @@ local function reactor_structure_badness(pos)
for z = pos1.z, pos2.z do
for y = pos1.y, pos2.y do
for x = pos1.x, pos2.x do
-- In the entire volume, make sure there is:
local cid = data[area:index(x, y, z)]
if x == pos1.x or x == pos2.x or
y == pos1.y or y == pos2.y or
z == pos1.z or z == pos2.z then
-- r=3 : Blast-resistant Concrete Block shell
if cid == c_blast_concrete then
blast_layer = blast_layer + 1
end
elseif x == pos1.x+1 or x == pos2.x-1 or
y == pos1.y+1 or y == pos2.y-1 or
z == pos1.z+1 or z == pos2.z-1 then
-- r=2 : Lead Block shell
if cid == c_lead then
lead_layer = lead_layer + 1
elseif cid == c_steel then
@ -175,6 +183,7 @@ local function reactor_structure_badness(pos)
elseif x == pos1.x+2 or x == pos2.x-2 or
y == pos1.y+2 or y == pos2.y-2 or
z == pos1.z+2 or z == pos2.z-2 then
-- r=1 : Water cooling
if cid == c_water_source or cid == c_water_flowing then
water_layer = water_layer + 1
end
@ -184,6 +193,8 @@ local function reactor_structure_badness(pos)
end
if steel_layer >= 96 then
-- Legacy: convert stainless steel to lead
-- Why don't we accept both without conversion?
for z = pos1.z+1, pos2.z-1 do
for y = pos1.y+1, pos2.y-1 do
for x = pos1.x+1, pos2.x-1 do
@ -206,6 +217,7 @@ local function reactor_structure_badness(pos)
if water_layer > 25 then water_layer = 25 end
if lead_layer > 96 then lead_layer = 96 end
if blast_layer > 216 then blast_layer = 216 end
-- Amount of missing blocks
return (25 - water_layer) + (96 - lead_layer) + (216 - blast_layer)
end
@ -297,7 +309,7 @@ local function run(pos, node)
end
meta:set_int("HV_EU_supply", 0)
meta:set_int("burn_time", 0)
meta:set_string("infotext", S("%s Idle"):format(reactor_desc))
meta:set_string("infotext", S("@1 Idle", reactor_desc))
technic.swap_node(pos, "technic:hv_nuclear_reactor_core")
meta:set_int("structure_accumulated_badness", 0)
siren_clear(pos, meta)

View File

@ -110,6 +110,40 @@ local function quarry_handle_purge(pos)
end
end
-- Determines whether the quarry can dig the node at "pos"
-- "startpos" is located a few nodes above the quarry in South West direction (X-, Z-)
-- Returns the node to dig (to avoid double minetest.get_node lookup)
local function quarry_can_dig_node(startpos, pos, quarry_owner)
if minetest.is_protected(pos, quarry_owner) then
return nil
end
local node = technic.get_or_load_node(pos) or minetest.get_node(pos)
local def = minetest.registered_nodes[node.name] or {diggable=false}
-- doors mod among other thing does NOT like a nil digger...
local fakedigger = pipeworks.create_fake_player({
name = quarry_owner
})
if not def.diggable or (def.can_dig and not def.can_dig(pos, fakedigger)) then
return nil
end
-- Find airlike nodes on top of the current node. The entire Y column must be free.
for ay = pos.y+1, startpos.y do
local checkpos = {x=pos.x, y=ay, z=pos.z}
local checknode = technic.get_or_load_node(checkpos) or minetest.get_node(checkpos)
local cdef = minetest.registered_nodes[checknode.name] or {}
local is_kind_of_gas = cdef.buildable_to and cdef.sunlight_propagates and not cdef.walkable
and not cdef.diggable and (cdef.drawtype == "airlike" or cdef.drawtype == "glasslike")
if not is_kind_of_gas then
return nil
end
end
return node
end
local function quarry_run(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
@ -153,35 +187,11 @@ local function quarry_run(pos, node)
vector.new(0, -ry, 0)),
vector.multiply(pdir, rp)),
vector.multiply(qdir, rq))
local can_dig = true
if can_dig and minetest.is_protected and minetest.is_protected(digpos, owner) then
can_dig = false
end
local dignode
if can_dig then
dignode = technic.get_or_load_node(digpos) or minetest.get_node(digpos)
local dignodedef = minetest.registered_nodes[dignode.name] or {diggable=false}
-- doors mod among other thing does NOT like a nil digger...
local fakedigger = pipeworks.create_fake_player({
name = owner
})
if not dignodedef.diggable or (dignodedef.can_dig and not dignodedef.can_dig(digpos, fakedigger)) then
can_dig = false
end
end
if can_dig then
for ay = startpos.y, digpos.y+1, -1 do
local checkpos = {x=digpos.x, y=ay, z=digpos.z}
local checknode = technic.get_or_load_node(checkpos) or minetest.get_node(checkpos)
if checknode.name ~= "air" then
can_dig = false
break
end
end
end
nd = nd + 1
if can_dig then
local dignode = quarry_can_dig_node(startpos, digpos, owner)
if dignode then
minetest.remove_node(digpos)
local drops = minetest.get_node_drops(dignode.name, "")
for _, dropped_item in ipairs(drops) do

View File

@ -9,5 +9,25 @@ minetest.register_craft({
}
})
if (minetest.get_modpath('everness')) then
minetest.register_craft({
output = 'technic:lv_grinder',
recipe = {
{'everness:coral_desert_stone', 'default:diamond', 'everness:coral_desert_stone'},
{'everness:coral_desert_stone', 'technic:machine_casing', 'everness:coral_desert_stone'},
{'technic:granite', 'technic:lv_cable', 'technic:granite'},
}
})
minetest.register_craft({
output = 'technic:lv_grinder',
recipe = {
{'everness:forsaken_desert_stone', 'default:diamond', 'everness:forsaken_desert_stone'},
{'everness:forsaken_desert_stone', 'technic:machine_casing', 'everness:forsaken_desert_stone'},
{'technic:granite', 'technic:lv_cable', 'technic:granite'},
}
})
end
technic.register_grinder({tier="LV", demand={200}, speed=1})

View File

@ -22,3 +22,6 @@ dofile(path.."/extractor.lua")
dofile(path.."/compressor.lua")
dofile(path.."/music_player.lua")
-- NEW LV LAMPS
dofile(path.."/led.lua")
dofile(path.."/lamp.lua")

View File

@ -0,0 +1,156 @@
-- LV Lamp
-- Illuminates a 7x7x3(H) volume below itself with light bright as the sun.
local S = technic.getter
local desc = S("@1 Lamp", S("LV"))
local active_desc = S("@1 Active", desc)
local unpowered_desc = S("@1 Unpowered", desc)
local off_desc = S("@1 Off", desc)
local demand = 50
-- Invisible light source node used for illumination
minetest.register_node("technic:dummy_light_source", {
description = S("Dummy light source node"),
inventory_image = "technic_dummy_light_source.png",
wield_image = "technic_dummy_light_source.png",
paramtype = "light",
drawtype = "airlike",
light_source = 14,
sunlight_propagates = true,
walkable = false,
buildable_to = true,
diggable = false,
pointable = false,
--drop = "", -- Intentionally allowed to drop itself
groups = {not_in_creative_inventory = 1}
})
local function illuminate(pos, active)
local pos1 = {x = pos.x - 3, y = pos.y - 1, z = pos.z - 3}
local pos2 = {x = pos.x + 3, y = pos.y - 3, z = pos.z + 3}
local find_node = active and "air" or "technic:dummy_light_source"
local set_node = {name = (active and "technic:dummy_light_source" or "air")}
for _,p in pairs(minetest.find_nodes_in_area(pos1, pos2, find_node)) do
minetest.set_node(p, set_node)
end
end
local function lamp_run(pos, node)
local meta = minetest.get_meta(pos)
if meta:get_int("LV_EU_demand") == 0 then
return -- Lamp is turned off
end
local eu_input = meta:get_int("LV_EU_input")
if node.name == "technic:lv_lamp_active" then
if eu_input < demand then
technic.swap_node(pos, "technic:lv_lamp")
meta:set_string("infotext", unpowered_desc)
illuminate(pos, false)
else
illuminate(pos, true)
end
elseif node.name == "technic:lv_lamp" then
if eu_input >= demand then
technic.swap_node(pos, "technic:lv_lamp_active")
meta:set_string("infotext", active_desc)
illuminate(pos, true)
end
end
end
local function lamp_toggle(pos, node, player)
if not player or minetest.is_protected(pos, player:get_player_name()) then
return
end
local meta = minetest.get_meta(pos)
if meta:get_int("LV_EU_demand") == 0 then
meta:set_string("infotext", active_desc)
meta:set_int("LV_EU_demand", demand)
else
illuminate(pos, false)
technic.swap_node(pos, "technic:lv_lamp")
meta:set_string("infotext", off_desc)
meta:set_int("LV_EU_demand", 0)
end
end
local common_fields = {
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {0.5,0.5,0.5,-0.5,-0.2,-0.5}
},
tiles = {
"technic_lv_lamp_top.png",
"technic_lv_lamp_bottom.png",
"technic_lv_lamp_side.png",
"technic_lv_lamp_side.png",
"technic_lv_lamp_side.png",
"technic_lv_lamp_side.png"
},
connect_sides = {"front", "back", "left", "right", "top"},
can_dig = technic.machine_can_dig,
technic_run = lamp_run,
on_destruct = illuminate,
on_rightclick = lamp_toggle
}
local ndef
ndef = {
description = desc,
groups = {cracky = 2, technic_machine = 1, technic_lv = 1},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", desc)
meta:set_int("LV_EU_demand", demand)
end
}
for k, v in pairs(common_fields) do
ndef[k] = v
end
minetest.register_node("technic:lv_lamp", ndef)
ndef = {
description = active_desc,
paramtype = "light",
light_source = 14,
drop = "technic:lv_lamp",
groups = {cracky = 2, technic_machine = 1, technic_lv = 1, not_in_creative_inventory = 1},
technic_on_disable = function(pos)
illuminate(pos, false)
technic.swap_node(pos, "technic:lv_lamp")
end,
}
for k, v in pairs(common_fields) do
ndef[k] = v
end
minetest.register_node("technic:lv_lamp_active", ndef)
technic.register_machine("LV", "technic:lv_lamp", technic.receiver)
technic.register_machine("LV", "technic:lv_lamp_active", technic.receiver)
minetest.register_craft({
output = "technic:lv_lamp",
recipe = {
{"default:glass", "default:glass", "default:glass"},
{"technic:lv_led", "technic:lv_led", "technic:lv_led"},
{"mesecons_materials:glue", "technic:lv_cable", "mesecons_materials:glue"},
}
})

View File

@ -0,0 +1,96 @@
-- LED
-- Intended primarily as a core component for LED lamps.
local S = technic.getter
local desc = S("@1 LED", S("LV"))
local active_desc = S("@1 Active", desc)
local unpowered_desc = S("@1 Unpowered", desc)
local demand = 5
local function led_run(pos, node)
local meta = minetest.get_meta(pos)
local eu_input = meta:get_int("LV_EU_input")
if eu_input < demand and node.name == "technic:lv_led_active" then
technic.swap_node(pos, "technic:lv_led")
meta:set_string("infotext", unpowered_desc)
elseif eu_input >= demand and node.name == "technic:lv_led" then
technic.swap_node(pos, "technic:lv_led_active")
meta:set_string("infotext", active_desc)
end
end
local common_fields = {
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {0.5, 0.5, 0.5, -0.5, 0.3, -0.5}
},
tiles = {
"technic_lv_led_top.png",
"technic_lv_led.png",
"technic_lv_led_side.png",
"technic_lv_led_side2.png",
"technic_lv_led_side2.png",
"technic_lv_led_side2.png",
},
connect_sides = {"front", "back", "left", "right", "top", "bottom"},
can_dig = technic.machine_can_dig,
technic_run = led_run,
}
local ndef
ndef = {
description = desc,
inventory_image = "technic_lv_led_inv.png",
sunlight_propagates = true,
groups = {cracky = 2, technic_machine = 1, technic_lv = 1},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", desc)
meta:set_int("LV_EU_demand", demand)
end,
}
for k, v in pairs(common_fields) do
ndef[k] = v
end
minetest.register_node("technic:lv_led", ndef)
ndef = {
description = active_desc,
paramtype = "light",
light_source = 9,
drop = "technic:lv_led",
groups = {cracky = 2, technic_machine = 1, technic_lv = 1, not_in_creative_inventory = 1},
technic_on_disable = function(pos)
technic.swap_node(pos, "technic:lv_led")
end,
}
for k, v in pairs(common_fields) do
ndef[k] = v
end
minetest.register_node("technic:lv_led_active", ndef)
technic.register_machine("LV", "technic:lv_led", technic.receiver)
technic.register_machine("LV", "technic:lv_led_active", technic.receiver)
minetest.register_craft({
output = "technic:lv_led 2",
recipe = {
{"", "homedecor:plastic_sheeting", ""},
{"homedecor:plastic_sheeting", "technic:doped_silicon_wafer", "homedecor:plastic_sheeting"},
{"", "basic_materials:silver_wire", ""},
},
replacements = { {"basic_materials:silver_wire", "basic_materials:empty_spool"}, },
})

View File

@ -324,6 +324,7 @@ for zp = 0, 1 do
on_rightclick = function(pos, node, placer, itemstack, pointed_thing)
if is_supported_node(itemstack:get_name()) then
-- Stripped down version of "core.item_place_node"
if minetest.is_protected(pos, placer:get_player_name()) then
minetest.log("action", placer:get_player_name()
.. " tried to place " .. itemstack:get_name()
@ -347,8 +348,7 @@ for zp = 0, 1 do
end
-- Run script hook
local callback = nil
for _, _ in ipairs(minetest.registered_on_placenodes) do
for _, callback in ipairs(minetest.registered_on_placenodes) do
-- Copy pos and node because callback can modify them
local pos_copy = { x = pos.x, y = pos.y, z = pos.z }
local newnode_copy = { name = def.name, param1 = 0, param2 = 0 }

View File

@ -92,7 +92,7 @@ local dirtab = {
local tube = {
insert_object = function(pos, node, stack, direction)
print(minetest.pos_to_string(direction), dirtab[direction.x+2+(direction.z+2)*2], node.param2)
--print(minetest.pos_to_string(direction), dirtab[direction.x+2+(direction.z+2)*2], node.param2)
if direction.y == 1
or (direction.y == 0 and dirtab[direction.x+2+(direction.z+2)*2] == node.param2) then
return stack
@ -106,7 +106,7 @@ local tube = {
end
end,
can_insert = function(pos, node, stack, direction)
print(minetest.pos_to_string(direction), dirtab[direction.x+2+(direction.z+2)*2], node.param2)
--print(minetest.pos_to_string(direction), dirtab[direction.x+2+(direction.z+2)*2], node.param2)
if direction.y == 1
or (direction.y == 0 and dirtab[direction.x+2+(direction.z+2)*2] == node.param2) then
return false
@ -192,10 +192,10 @@ function technic.register_battery_box(data)
end
local run = function(pos, node)
local below = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z})
local meta = minetest.get_meta(pos)
local meta = minetest.get_meta(pos)
local network_id = tonumber(meta:get_string(tier.."_network"))
if not technic.is_tier_cable(below.name, tier) then
if not technic.networks[network_id] then
meta:set_string("infotext", S("%s Battery Box Has No Network"):format(tier))
return
end
@ -409,28 +409,23 @@ minetest.register_on_player_receive_fields(
end
)
local function default_get_charge(itemstack)
function technic.get_charge(itemstack)
-- check if is chargable
local tool_name = itemstack:get_name()
if not technic.power_tools[tool_name] then
return 0, 0
end
-- Set meta data for the tool if it didn't do it itself
local item_meta = minetest.deserialize(itemstack:get_metadata()) or {}
if not item_meta.charge then
item_meta.charge = 0
end
return item_meta.charge, technic.power_tools[tool_name]
local item_meta = technic.get_stack_meta(itemstack)
return item_meta:get_int("technic:charge"), technic.power_tools[tool_name]
end
local function default_set_charge(itemstack, charge)
function technic.set_charge(itemstack, charge)
local tool_name = itemstack:get_name()
if technic.power_tools[tool_name] then
technic.set_RE_wear(itemstack, charge, technic.power_tools[tool_name])
end
local item_meta = minetest.deserialize(itemstack:get_metadata()) or {}
item_meta.charge = charge
itemstack:set_metadata(minetest.serialize(item_meta))
local item_meta = technic.get_stack_meta(itemstack)
item_meta:set_int("technic:charge", charge)
end
function technic.charge_tools(meta, batt_charge, charge_step)
@ -442,8 +437,8 @@ function technic.charge_tools(meta, batt_charge, charge_step)
-- get callbacks
local src_def = src_stack:get_definition()
local technic_get_charge = src_def.technic_get_charge or default_get_charge
local technic_set_charge = src_def.technic_set_charge or default_set_charge
local technic_get_charge = src_def.technic_get_charge or technic.get_charge
local technic_set_charge = src_def.technic_set_charge or technic.set_charge
-- get tool charge
local tool_charge, item_max_charge = technic_get_charge(src_stack)
@ -476,8 +471,8 @@ function technic.discharge_tools(meta, batt_charge, charge_step, max_charge)
-- get callbacks
local src_def = src_stack:get_definition()
local technic_get_charge = src_def.technic_get_charge or default_get_charge
local technic_set_charge = src_def.technic_set_charge or default_set_charge
local technic_get_charge = src_def.technic_get_charge or technic.get_charge
local technic_set_charge = src_def.technic_set_charge or technic.set_charge
-- get tool charge
local tool_charge, item_max_charge = technic_get_charge(src_stack)

View File

@ -11,6 +11,13 @@ function technic.get_cable_tier(name)
return cable_tier[name]
end
function technic.register_cable_tier(name, tier)
assert(technic.machines[tier], "Tier does not exist")
assert(type(name) == "string", "Invalid node name")
cable_tier[name] = tier
end
local function check_connections(pos)
-- Build a table of all machines
local machines = {}
@ -36,84 +43,106 @@ local function check_connections(pos)
return connections
end
local function clear_networks(pos)
local clear_networks
local function clear_network(network_id)
if not network_id then
return
end
for _,v in pairs(technic.networks[network_id].all_nodes) do
local pos1 = minetest.hash_node_position(v)
technic.cables[pos1] = nil
end
local network_bckup = technic.networks[network_id]
technic.networks[network_id] = nil
for _,n_pos in pairs(network_bckup.PR_nodes) do
clear_networks(n_pos)
end
for _,n_pos in pairs(network_bckup.RE_nodes) do
clear_networks(n_pos)
end
for _,n_pos in pairs(network_bckup.BA_nodes) do
clear_networks(n_pos)
end
end
clear_networks = function(pos)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
local placed = node.name ~= "air"
local positions = check_connections(pos)
if #positions < 1 then return end
local dead_end = #positions == 1
for _,connected_pos in pairs(positions) do
local net = technic.cables[minetest.hash_node_position(connected_pos)]
if net and technic.networks[net] then
if dead_end and placed then
-- Dead end placed, add it to the network
-- Get the network
local network_id = technic.cables[minetest.hash_node_position(positions[1])]
if not network_id then
-- We're evidently not on a network, nothing to add ourselves to
return
end
local sw_pos = minetest.get_position_from_hash(network_id)
sw_pos.y = sw_pos.y + 1
local network = technic.networks[network_id]
local tier = network.tier
-- Actually add it to the (cached) network
-- This is similar to check_node_subp
if #positions == 1 then
if placed then
-- Dead end placed, add it to the network
-- Get the network
local network_id = technic.cables[minetest.hash_node_position(positions[1])]
if not network_id then
-- We're evidently not on a network, nothing to add ourselves to
return
end
local network = technic.networks[network_id]
local tier = network.tier
-- Actually add it to the (cached) network
-- !! IMPORTANT: ../switching_station.lua -> check_node_subp() must be kept in sync
if technic.is_tier_cable(node.name, tier) then
technic.cables[minetest.hash_node_position(pos)] = network_id
pos.visited = 1
if technic.is_tier_cable(node.name, tier) then
-- Found a cable
table.insert(network.all_nodes,pos)
elseif technic.machines[tier][node.name] then
-- Found a machine
local eu_type = technic.machines[tier][node.name]
meta:set_string(tier.."_network", minetest.pos_to_string(sw_pos))
if eu_type == technic.producer then
table.insert(network.PR_nodes, pos)
elseif eu_type == technic.receiver then
table.insert(network.RE_nodes, pos)
elseif eu_type == technic.producer_receiver then
table.insert(network.PR_nodes, pos)
table.insert(network.RE_nodes, pos)
elseif eu_type == technic.battery then
table.insert(network.BA_nodes, pos)
end
-- Note: SPECIAL (i.e. switching station) is not traversed!
table.insert(network.all_nodes,pos)
elseif technic.machines[tier][node.name] then
-- Found a machine
local eu_type = technic.machines[tier][node.name]
meta:set_string(tier.."_network", string.format("%.20g", network_id))
meta:set_int(tier.."_EU_timeout", 2)
if eu_type == technic.producer then
table.insert(network.PR_nodes, pos)
elseif eu_type == technic.receiver then
table.insert(network.RE_nodes, pos)
elseif eu_type == technic.producer_receiver then
table.insert(network.PR_nodes, pos)
table.insert(network.RE_nodes, pos)
elseif eu_type == technic.battery then
table.insert(network.BA_nodes, pos)
end
elseif dead_end and not placed then
-- Dead end removed, remove it from the network
-- Get the network
local network_id = technic.cables[minetest.hash_node_position(positions[1])]
if not network_id then
-- We're evidently not on a network, nothing to add ourselves to
return
end
local network = technic.networks[network_id]
-- Note: SPECIAL (i.e. switching station) is not traversed!
end
else
-- Dead end removed, remove it from the network
-- Get the network
local network_id = technic.cables[minetest.hash_node_position(positions[1])]
if not network_id then
-- We're evidently not on a network, nothing to add ourselves to
return
end
local network = technic.networks[network_id]
-- Search for and remove machine
technic.cables[minetest.hash_node_position(pos)] = nil
for tblname,table in pairs(network) do
if tblname ~= "tier" then
for machinenum,machine in pairs(table) do
if machine.x == pos.x
and machine.y == pos.y
and machine.z == pos.z then
table[machinenum] = nil
end
-- Search for and remove machine
technic.cables[minetest.hash_node_position(pos)] = nil
for tblname,table in pairs(network) do
if tblname ~= "tier" then
for machinenum,machine in pairs(table) do
if machine.x == pos.x
and machine.y == pos.y
and machine.z == pos.z then
table[machinenum] = nil
end
end
end
else
-- Not a dead end, so the whole network needs to be recalculated
for _,v in pairs(technic.networks[net].all_nodes) do
local pos1 = minetest.hash_node_position(v)
technic.cables[pos1] = nil
end
technic.networks[net] = nil
end
end
return
end
clear_network(technic.cables[minetest.hash_node_position(pos)])
for _,connected_pos in pairs(positions) do
local network_id = technic.cables[minetest.hash_node_position(connected_pos)]
-- Not a dead end, so the whole network needs to be recalculated
clear_network(network_id)
end
end
@ -163,7 +192,7 @@ function technic.register_cable(tier, size)
connects_to = {"group:technic_"..ltier.."_cable",
"group:technic_"..ltier, "group:technic_all_tiers"},
on_construct = clear_networks,
on_destruct = clear_networks,
after_destruct = clear_networks,
})
local xyz = {
@ -203,7 +232,7 @@ function technic.register_cable(tier, size)
connects_to = {"group:technic_"..ltier.."_cable",
"group:technic_"..ltier, "group:technic_all_tiers"},
on_construct = clear_networks,
on_destruct = clear_networks,
after_destruct = clear_networks,
}
def.node_box.fixed = {
{-size, -size, -size, size, size, size},

View File

@ -8,6 +8,71 @@ function technic.register_compressor_recipe(data)
technic.register_recipe("compressing", data)
end
-- Defuse the default recipes, since we have
-- the compressor to take over in a more realistic manner.
local crafts_to_clear = {
"default:desert_sand",
"default:sand",
"default:silver_sand",
}
local dependent_crafts_to_clear = {
everness = {
"everness:coral_sand",
"everness:coral_forest_deep_ocean_sand",
"everness:coral_white_sand",
"everness:crystal_sand",
"everness:cursed_sand",
"everness:cursed_lands_deep_ocean_sand",
"everness:crystal_forest_deep_ocean_sand",
"everness:mineral_sand",
},
nether = {
"nether:brick",
"nether:brick_compressed",
"nether:rack",
"nether:rack_deep",
},
}
-- Add dependent recipes to main collection of
-- recipes to be cleared if their mods are used.
for dependency, crafts in pairs(dependent_crafts_to_clear) do
if minetest.get_modpath(dependency) then
for _, craft_entry in ipairs(crafts) do
table.insert(crafts_to_clear, craft_entry)
end
end
end
-- Clear recipes
for _, craft_name in ipairs(crafts_to_clear) do
-- Regular bricks are 2x2 shaped, nether bricks are 3x3 shaped (irregular)
local is_regular = string.sub(craft_name, 1, 12) ~= "nether:brick"
local shaped_recipe
if is_regular then
shaped_recipe = {
{craft_name, craft_name},
{craft_name, craft_name},
}
else
shaped_recipe = {
{craft_name, craft_name, craft_name},
{craft_name, craft_name, craft_name},
{craft_name, craft_name, craft_name},
}
end
minetest.clear_craft({
type = "shaped",
recipe = shaped_recipe,
})
end
--
-- Compile compressor recipes
--
local recipes = {
{"default:snowblock", "default:ice"},
{"default:sand 2", "default:sandstone"},
@ -21,27 +86,36 @@ local recipes = {
{"technic:uranium35_ingot 5", "technic:uranium_fuel"},
}
-- defuse the default sandstone recipe, since we have the compressor to take over in a more realistic manner
minetest.clear_craft({
recipe = {
{"default:sand", "default:sand"},
{"default:sand", "default:sand"},
local dependent_recipes = {
everness = {
{"everness:coral_deep_ocean_sand 2", "everness:coral_deep_ocean_sandstone_block"},
{"everness:coral_sand 2", "everness:coral_sandstone"},
{"everness:coral_white_sand 2", "everness:coral_white_sandstone"},
{"everness:crystal_forest_deep_ocean_sand 2", "everness:crystal_forest_deep_ocean_sandstone_block"},
{"everness:crystal_sand 2", "everness:crystal_sandstone"},
{"everness:cursed_lands_deep_ocean_sand 2", "everness:cursed_lands_deep_ocean_sandstone_block"},
{"everness:cursed_sand 2", "everness:cursed_sandstone_block"},
{"everness:mineral_sand 2", "everness:mineral_sandstone"},
},
})
minetest.clear_craft({
recipe = {
{"default:desert_sand", "default:desert_sand"},
{"default:desert_sand", "default:desert_sand"},
nether = {
{"nether:brick 9", "nether:brick_compressed"},
{"nether:brick_compressed 9", "nether:nether_lump"},
{"nether:rack", "nether:brick",},
{"nether:rack_deep", "nether:brick_deep"},
},
})
minetest.clear_craft({
recipe = {
{"default:silver_sand", "default:silver_sand"},
{"default:silver_sand", "default:silver_sand"},
},
})
}
-- Add dependent recipes to main recipe collection
-- if their mods are used.
for dependency, recipes_to_add in pairs(dependent_recipes) do
if minetest.get_modpath(dependency) then
for _, recipe_entry in ipairs(recipes_to_add) do
table.insert(recipes, recipe_entry)
end
end
end
-- Register compressor recipes
for _, data in pairs(recipes) do
technic.register_compressor_recipe({input = {data[1]}, output = data[2]})
end

View File

@ -23,6 +23,8 @@ local recipes = {
{"technic:sulfur_lump", "technic:sulfur_dust 2"},
{"default:stone", "technic:stone_dust"},
{"default:sand", "technic:stone_dust"},
{"default:desert_sand", "technic:stone_dust"},
{"default:silver_sand", "technic:stone_dust"},
-- Other
{"default:cobble", "default:gravel"},
@ -34,49 +36,73 @@ local recipes = {
{"default:ice", "default:snowblock"},
}
local dependent_recipes = {
-- Sandstones
everness = {
{"everness:coral_deep_ocean_sandstone_block", "everness:coral_deep_ocean_sand 2"},
{"everness:coral_sandstone", "everness:coral_sand 2"},
{"everness:coral_white_sandstone", "everness:coral_white_sand 2"},
{"everness:crystal_forest_deep_ocean_sandstone_block", "everness:crystal_forest_deep_ocean_sand 2"},
{"everness:crystal_sandstone", "everness:crystal_sand 2"},
{"everness:cursed_lands_deep_ocean_sandstone_block", "everness:cursed_lands_deep_ocean_sand 2"},
{"everness:cursed_sandstone_block", "everness:cursed_sand 2"},
{"everness:mineral_sandstone", "everness:mineral_sand 2"},
-- Lumps and wheat
{"everness:pyrite_lump", "technic:pyrite_dust 2"},
},
farming = {
{"farming:seed_wheat", "farming:flour 1"},
},
gloopores = {
{"gloopores:alatro_lump", "technic:alatro_dust 2"},
{"gloopores:kalite_lump", "technic:kalite_dust 2"},
{"gloopores:arol_lump", "technic:arol_dust 2"},
{"gloopores:talinite_lump", "technic:talinite_dust 2"},
{"gloopores:akalin_lump", "technic:akalin_dust 2"},
},
homedecor = {
{"home_decor:brass_ingot", "technic:brass_dust 1"},
},
moreores = {
{"moreores:mithril_lump", "technic:mithril_dust 2"},
{"moreores:silver_lump", "technic:silver_dust 2"},
},
nether = {
{"nether:nether_lump", "technic:nether_dust 2"},
},
}
for dependency, materials_to_add in pairs(dependent_recipes) do
if minetest.get_modpath(dependency) then
for _, material_entry in ipairs(materials_to_add) do
table.insert(recipes, material_entry)
end
end
end
-- defuse the sandstone -> 4 sand recipe to avoid infinite sand bugs (also consult the inverse compressor recipe)
minetest.clear_craft({
recipe = {
{"default:sandstone"}
},
recipe = {{"default:sandstone"}},
})
minetest.clear_craft({
recipe = {
{"default:desert_sandstone"}
},
recipe = {{"default:desert_sandstone"}},
})
minetest.clear_craft({
recipe = {
{"default:silver_sandstone"}
},
recipe = {{"default:silver_sandstone"}},
})
if minetest.get_modpath("farming") then
table.insert(recipes, {"farming:seed_wheat", "farming:flour 1"})
if minetest.get_modpath("everness") then
minetest.clear_craft({
recipe = {{"everness:mineral_sandstone"}},
})
-- Currently (2024-03-09), there seem to be no reverse recipes for any of the other everness sandstones.
end
if minetest.get_modpath("moreores") then
table.insert(recipes, {"moreores:mithril_lump", "technic:mithril_dust 2"})
table.insert(recipes, {"moreores:silver_lump", "technic:silver_dust 2"})
end
if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
table.insert(recipes, {"gloopores:alatro_lump", "technic:alatro_dust 2"})
table.insert(recipes, {"gloopores:kalite_lump", "technic:kalite_dust 2"})
table.insert(recipes, {"gloopores:arol_lump", "technic:arol_dust 2"})
table.insert(recipes, {"gloopores:talinite_lump", "technic:talinite_dust 2"})
table.insert(recipes, {"gloopores:akalin_lump", "technic:akalin_dust 2"})
end
if minetest.get_modpath("homedecor") then
table.insert(recipes, {"home_decor:brass_ingot", "technic:brass_dust 1"})
end
for _, data in pairs(recipes) do
for _, data in ipairs(recipes) do
technic.register_grinder_recipe({input = {data[1]}, output = data[2]})
end
-- dusts
-- Dusts
local function register_dust(name, ingot)
local lname = string.lower(name)
lname = string.gsub(lname, ' ', '_')
@ -94,33 +120,57 @@ local function register_dust(name, ingot)
end
end
-- Sorted alphibeticaly
register_dust("Brass", "basic_materials:brass_ingot")
register_dust("Bronze", "default:bronze_ingot")
register_dust("Carbon Steel", "technic:carbon_steel_ingot")
register_dust("Cast Iron", "technic:cast_iron_ingot")
register_dust("Chernobylite", "technic:chernobylite_block")
register_dust("Chromium", "technic:chromium_ingot")
register_dust("Coal", nil)
register_dust("Copper", "default:copper_ingot")
register_dust("Lead", "technic:lead_ingot")
register_dust("Gold", "default:gold_ingot")
register_dust("Mithril", "moreores:mithril_ingot")
register_dust("Silver", "moreores:silver_ingot")
register_dust("Stainless Steel", "technic:stainless_steel_ingot")
register_dust("Stone", "default:stone")
register_dust("Sulfur", nil)
register_dust("Tin", "default:tin_ingot")
register_dust("Wrought Iron", "technic:wrought_iron_ingot")
register_dust("Zinc", "technic:zinc_ingot")
if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
register_dust("Akalin", "glooptest:akalin_ingot")
register_dust("Alatro", "glooptest:alatro_ingot")
register_dust("Arol", "glooptest:arol_ingot")
register_dust("Kalite", nil)
register_dust("Talinite", "glooptest:talinite_ingot")
-- Sorted alphabetically
local dusts = {
{"Brass", "basic_materials:brass_ingot"},
{"Bronze", "default:bronze_ingot"},
{"Carbon Steel", "technic:carbon_steel_ingot"},
{"Cast Iron", "technic:cast_iron_ingot"},
{"Chernobylite", "technic:chernobylite_block"},
{"Chromium", "technic:chromium_ingot"},
{"Coal", nil},
{"Copper", "default:copper_ingot"},
{"Lead", "technic:lead_ingot"},
{"Gold", "default:gold_ingot"},
{"Mithril", "moreores:mithril_ingot"},
{"Silver", "moreores:silver_ingot"},
{"Stainless Steel", "technic:stainless_steel_ingot"},
{"Stone", "default:stone"},
{"Sulfur", nil},
{"Tin", "default:tin_ingot"},
{"Wrought Iron", "technic:wrought_iron_ingot"},
{"Zinc", "technic:zinc_ingot"},
}
local dependent_dusts = {
everness = {
{"Pyrite", "everness:pyrite_ingot"},
},
gloopores = {
{"Akalin", "glooptest:akalin_ingot"},
{"Alatro", "glooptest:alatro_ingot"},
{"Arol", "glooptest:arol_ingot"},
{"Kalite", nil},
{"Talinite", "glooptest:talinite_ingot"},
},
nether = {
{"Nether", "nether:nether_ingot"},
},
}
for dependency, dusts_to_add in pairs(dependent_dusts) do
if minetest.get_modpath(dependency) then
for _, dust_entry in pairs(dusts_to_add) do
table.insert(dusts, dust_entry)
end
end
end
for _, data in ipairs(dusts) do
register_dust(data[1], data[2])
end
-- Uranium
for p = 0, 35 do
local nici = (p ~= 0 and p ~= 7 and p ~= 35) and 1 or nil
local psuffix = p == 7 and "" or p
@ -156,6 +206,7 @@ for pa = 0, 34 do
end
end
-- Fuels
minetest.register_craft({
type = "fuel",
recipe = "technic:coal_dust",

View File

@ -32,7 +32,10 @@ function technic.register_recipe_type(typename, origdata)
end
local function get_recipe_index(items)
if not items or type(items) ~= "table" then return false end
if type(items) ~= "table" then
return false
end
local l = {}
for i, stack in ipairs(items) do
l[i] = ItemStack(stack):get_name()
@ -75,22 +78,21 @@ local function register_recipe(typename, data)
end
if (have_cg or have_i3) and technic.recipes[typename].output_size == 1 then
local result = data.output
if (type(result)=="table") then
if type(result) == "table" then
result = result[1]
end
local items = table.concat(data.input, ", ")
if have_cg and craftguide.register_craft then
craftguide.register_craft({
type = typename,
result = result,
items = {items},
items = data.input,
})
end
if have_i3 then
i3.register_craft({
type = typename,
result = result,
items = {items},
items = data.input,
})
end
end

View File

@ -120,7 +120,7 @@ local run = function(pos, node, run_stage)
return
end
local remain = 0.9
local efficiency = 0.9
-- Machine information
local machine_name = S("Supply Converter")
local meta = minetest.get_meta(pos)
@ -133,7 +133,6 @@ local run = function(pos, node, run_stage)
enabled = enabled == "1"
end
enabled = enabled and (meta:get_int("mesecon_mode") == 0 or meta:get_int("mesecon_effect") ~= 0)
local demand = enabled and meta:get_int("power") or 0
local pos_up = {x=pos.x, y=pos.y+1, z=pos.z}
local pos_down = {x=pos.x, y=pos.y-1, z=pos.z}
@ -144,14 +143,37 @@ local run = function(pos, node, run_stage)
local to = technic.get_cable_tier(name_down)
if from and to then
local input = meta:get_int(from.."_EU_input")
meta:set_int(from.."_EU_demand", demand)
meta:set_int(from.."_EU_supply", 0)
meta:set_int(to.."_EU_demand", 0)
meta:set_int(to.."_EU_supply", input * remain)
meta:set_string("infotext", S("@1 (@2 @3 -> @4 @5)", machine_name,
technic.EU_string(input), from,
technic.EU_string(input * remain), to))
-- Get the "to" network switching station for EU demand calculation
local network_hash = technic.cables[minetest.hash_node_position(pos_down)]
local network = network_hash and minetest.get_position_from_hash(network_hash)
local sw_pos = network and {x=network.x,y=network.y+1,z=network.z}
local timeout = 0
for tier in pairs(technic.machines) do
-- Supply converter must be connected to a network
timeout = math.max(meta:get_int(tier.."_EU_timeout"), timeout)
end
if timeout > 0 and sw_pos and minetest.get_node(sw_pos).name == "technic:switching_station" then
local sw_meta = minetest.get_meta(sw_pos)
local demand = 0
if enabled then
-- Reverse evaluate the required machine and round to a nice number
demand = sw_meta:get_int("ba_demand") + sw_meta:get_int("demand")
demand = 100 * math.ceil(demand / efficiency / 100)
-- Do not draw more than the limit
demand = math.min(demand, meta:get_int("power"))
end
local input = meta:get_int(from.."_EU_input") -- actual input
meta:set_int(from.."_EU_demand", demand) -- desired input
meta:set_int(from.."_EU_supply", 0)
meta:set_int(to.."_EU_demand", 0)
meta:set_int(to.."_EU_supply", input * efficiency)
meta:set_string("infotext", S("@1 (@2 @3 -> @4 @5)", machine_name,
technic.EU_string(input), from,
technic.EU_string(input * efficiency), to))
else
meta:set_string("infotext",S("%s Has No Network"):format(machine_name))
end
else
meta:set_string("infotext", S("%s Has Bad Cabling"):format(machine_name))
if to then

View File

@ -97,12 +97,14 @@ local function flatten(map)
return list
end
-- Add a wire node to the LV/MV/HV network
-- Returns: indicator whether the cable is new in the network
-- Add a node to the LV/MV/HV network
-- Returns: indicator whether the node is new in the network
local hash_node_position = minetest.hash_node_position
local function add_network_node(nodes, pos, network_id)
local node_id = hash_node_position(pos)
technic.cables[node_id] = network_id
if network_id then
technic.cables[node_id] = network_id
end
if nodes[node_id] then
return false
end
@ -117,6 +119,7 @@ local function add_cable_node(nodes, pos, network_id, queue)
end
-- Generic function to add found connected nodes to the right classification array
-- !! IMPORTANT: register/cables.lua -> clear_networks() must be kept in sync
local check_node_subp = function(network, pos, machines, sw_pos, from_below, network_id, queue)
technic.get_or_load_node(pos)
local name = minetest.get_node(pos).name
@ -133,21 +136,33 @@ local check_node_subp = function(network, pos, machines, sw_pos, from_below, net
--dprint(name.." is a "..machines[name])
local meta = minetest.get_meta(pos)
meta:set_string(network.tier.."_network", minetest.pos_to_string(sw_pos))
-- Normal tostring() does not have enough precision, neither does meta:set_int()
-- Lua 5.1 bug: Cannot use hexadecimal notation for compression (see LuaJIT #911)
local network_str = string.format("%.20g", network_id)
local network_key = network.tier.."_network"
local m_network_str = meta:get_string(network_key)
if m_network_str == "" then
meta:set_string(network_key, network_str)
else
if m_network_str ~= network_str then
return
end
end
if eu_type == technic.producer then
add_network_node(network.PR_nodes, pos, network_id)
add_network_node(network.PR_nodes, pos)
elseif eu_type == technic.receiver then
add_network_node(network.RE_nodes, pos, network_id)
add_network_node(network.RE_nodes, pos)
elseif eu_type == technic.producer_receiver then
add_network_node(network.PR_nodes, pos, network_id)
add_network_node(network.RE_nodes, pos, network_id)
add_network_node(network.PR_nodes, pos)
add_network_node(network.RE_nodes, pos)
elseif eu_type == technic.battery then
add_network_node(network.BA_nodes, pos, network_id)
add_network_node(network.BA_nodes, pos)
elseif eu_type == "SPECIAL" and from_below and
not vector.equals(pos, sw_pos) then
-- Another switching station -> disable it
add_network_node(network.SP_nodes, pos, network_id)
add_network_node(network.SP_nodes, pos)
meta:set_int("active", 0)
end
@ -190,7 +205,6 @@ local get_network = function(sw_pos, cable_pos, tier)
end
return cached.PR_nodes, cached.BA_nodes, cached.RE_nodes
end
local machines = technic.machines[tier]
local network = {
tier = tier,
@ -354,6 +368,8 @@ minetest.register_abm({
BA_eu_supply = BA_eu_supply + meta1:get_int(eu_supply_str)
BA_eu_demand = BA_eu_demand + meta1:get_int(eu_demand_str)
end
-- Expose value for the supply converter
meta:set_int("ba_demand", BA_eu_demand)
--dprint("Total BA supply:"..BA_eu_supply)
--dprint("Total BA demand:"..BA_eu_demand)
@ -450,6 +466,7 @@ local function switching_station_timeout_count(pos, tier)
local meta = minetest.get_meta(pos)
local timeout = meta:get_int(tier.."_EU_timeout")
if timeout <= 0 then
meta:set_string(tier.."_network", "")
meta:set_int(tier.."_EU_input", 0) -- Not needed anymore <-- actually, it is for supply converter
return true
else
@ -463,22 +480,29 @@ minetest.register_abm({
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local has_network = false
local technic_machine = false
for tier, machines in pairs(technic.machines) do
if machines[node.name] and switching_station_timeout_count(pos, tier) then
local nodedef = minetest.registered_nodes[node.name]
if nodedef then
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("%s Has No Network"):format(nodedef.description))
end
if nodedef and nodedef.technic_disabled_machine_name then
node.name = nodedef.technic_disabled_machine_name
minetest.swap_node(pos, node)
end
if nodedef and nodedef.technic_on_disable then
nodedef.technic_on_disable(pos, node)
if machines[node.name] then
technic_machine = true
if not switching_station_timeout_count(pos, tier) then
has_network = true
end
end
end
if technic_machine and not has_network then
local nodedef = minetest.registered_nodes[node.name]
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("%s Has No Network"):format(nodedef.description))
if nodedef.technic_disabled_machine_name then
node.name = nodedef.technic_disabled_machine_name
minetest.swap_node(pos, node)
end
if nodedef.technic_on_disable then
nodedef.technic_on_disable(pos, node)
end
end
end,
})

View File

@ -1,3 +1,3 @@
name = technic
depends = default, pipeworks, technic_worldgen, basic_materials
optional_depends = bucket, screwdriver, mesecons, mesecons_mvps, digilines, digiline_remote, intllib, unified_inventory, vector_extras, dye, craftguide,i3
optional_depends = bucket, screwdriver, mesecons, mesecons_mvps, digilines, digiline_remote, intllib, unified_inventory, vector_extras, dye, craftguide, i3, everness, nether

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 743 B

View File

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 181 B

View File

Before

Width:  |  Height:  |  Size: 251 B

After

Width:  |  Height:  |  Size: 251 B

View File

Before

Width:  |  Height:  |  Size: 168 B

After

Width:  |  Height:  |  Size: 168 B

View File

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 916 B

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 346 B

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 674 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Some files were not shown because too many files have changed in this diff Show More