mirror of
https://github.com/minetest-mods/technic.git
synced 2025-07-16 15:20:32 +02:00
Compare commits
8 Commits
d2b68a6bef
...
bce5306abe
Author | SHA1 | Date | |
---|---|---|---|
bce5306abe | |||
167ab93905 | |||
5beb84bed9 | |||
f9b0906a82 | |||
9a39a94272 | |||
349676f243 | |||
0f6bdb1bde | |||
0211c582e9 |
24
.luacheckrc
24
.luacheckrc
@ -1,6 +1,8 @@
|
||||
unused_args = false
|
||||
allow_defined_top = true
|
||||
max_line_length = 999
|
||||
max_line_length = 150
|
||||
-- Allow shadowed variables (callbacks in callbacks)
|
||||
redefined = false
|
||||
|
||||
globals = {
|
||||
"technic", "minetest",
|
||||
@ -32,19 +34,7 @@ read_globals = {
|
||||
"craftguide", "i3"
|
||||
}
|
||||
|
||||
files["concrete/init.lua"].ignore = { "steel_ingot" }
|
||||
files["technic/machines/MV/tool_workshop.lua"].ignore = { "pos" }
|
||||
files["technic/machines/other/frames.lua"].ignore = { "item_texture", "item_type", "adj", "connected", "" }
|
||||
files["technic/machines/register/battery_box.lua"].ignore = { "pos", "tube_upgrade" }
|
||||
files["technic/machines/register/cables.lua"].ignore = { "name", "from_below", "p" }
|
||||
files["technic/machines/register/common.lua"].ignore = { "result" }
|
||||
|
||||
files["technic/machines/register/generator.lua"].ignore = { "node" }
|
||||
files["technic/machines/switching_station.lua"].ignore = { "pos1", "tier", "poshash" }
|
||||
files["technic/radiation.lua"].ignore = { "LAVA_VISC" }
|
||||
files["technic/tools/chainsaw.lua"].ignore = { "pos" }
|
||||
files["technic/tools/mining_drill.lua"].ignore = { "mode" }
|
||||
files["technic_chests/register.lua"].ignore = { "fs_helpers", "name", "locked_after_place" }
|
||||
|
||||
files["technic_cnc/cnc.lua"].ignore = { "multiplier" }
|
||||
files["wrench/init.lua"].ignore = { "name", "stack" }
|
||||
-- Loop warning
|
||||
files["technic/machines/other/frames.lua"].ignore = { "" }
|
||||
-- Long lines
|
||||
files["technic_cnc/cnc_api.lua"].ignore = { "" }
|
16
LICENSE.txt
Normal file
16
LICENSE.txt
Normal file
@ -0,0 +1,16 @@
|
||||
Minetest Mod: technic
|
||||
Copyright (C) 2012-2022 RealBadAngel and contributors
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
@ -24,7 +24,8 @@ world. A few notable features:
|
||||
|
||||
## FAQ
|
||||
|
||||
The modpack is explained in the [Manual](manual.md) included in this repository.
|
||||
The modpack is explained in the **[Manual](manual.md)** included in this repository.
|
||||
Machine and tool descriptions can be found on the **[GitHub Wiki](https://github.com/minetest-mods/technic/wiki)**.
|
||||
|
||||
1. My technic circuit doesn't work. No power is distributed.
|
||||
* Make sure you have a switching station connected.
|
||||
@ -32,13 +33,13 @@ The modpack is explained in the [Manual](manual.md) included in this repository.
|
||||
* Each machine type requires its own cable type. If you do not have a
|
||||
matching circuit, consider using a "Supply Converter" for simplicity.
|
||||
|
||||
The API documentation can be found here: [Technic API](technic/doc/api.md)
|
||||
For modders: **[Technic Lua API](technic/doc/api.md)**
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Unless otherwise stated, all components of this modpack are licensed under the
|
||||
LGPLv2 or later. See also the individual mod folders for their
|
||||
[LGPLv2 or later](LICENSE.txt). See also the individual mod folders for their
|
||||
secondary/alternate licenses, if any.
|
||||
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
default
|
||||
basic_materials
|
||||
intllib?
|
||||
moreblocks?
|
@ -16,13 +16,6 @@ for i = 32, 63 do
|
||||
"technic:concrete_post_with_platform")
|
||||
end
|
||||
|
||||
local steel_ingot
|
||||
if minetest.get_modpath("technic_worldgen") then
|
||||
steel_ingot = "technic:carbon_steel_ingot"
|
||||
else
|
||||
steel_ingot = "default:steel_ingot"
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:concrete_post_platform 6',
|
||||
recipe = {
|
||||
|
@ -1,9 +0,0 @@
|
||||
default
|
||||
technic_worldgen
|
||||
basic_materials
|
||||
concrete
|
||||
unifieddyes?
|
||||
intllib?
|
||||
moreblocks?
|
||||
steel?
|
||||
streetsmod?
|
@ -57,36 +57,47 @@ if minetest.get_modpath("moreblocks") then
|
||||
tiles={"technic_stainless_steel_block.png"},
|
||||
})
|
||||
|
||||
function register_technic_stairs_alias(modname, origname, newmod, newname)
|
||||
minetest.register_alias(modname .. ":slab_" .. origname, newmod..":slab_" .. newname)
|
||||
minetest.register_alias(modname .. ":slab_" .. origname .. "_inverted", newmod..":slab_" .. newname .. "_inverted")
|
||||
minetest.register_alias(modname .. ":slab_" .. origname .. "_wall", newmod..":slab_" .. newname .. "_wall")
|
||||
minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter", newmod..":slab_" .. newname .. "_quarter")
|
||||
minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter_inverted", newmod..":slab_" .. newname .. "_quarter_inverted")
|
||||
minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter_wall", newmod..":slab_" .. newname .. "_quarter_wall")
|
||||
minetest.register_alias(modname .. ":slab_" .. origname .. "_three_quarter", newmod..":slab_" .. newname .. "_three_quarter")
|
||||
minetest.register_alias(modname .. ":slab_" .. origname .. "_three_quarter_inverted", newmod..":slab_" .. newname .. "_three_quarter_inverted")
|
||||
minetest.register_alias(modname .. ":slab_" .. origname .. "_three_quarter_wall", newmod..":slab_" .. newname .. "_three_quarter_wall")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname, newmod..":stair_" .. newname)
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_inverted", newmod..":stair_" .. newname .. "_inverted")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall", newmod..":stair_" .. newname .. "_wall")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half", newmod..":stair_" .. newname .. "_wall_half")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half_inverted", newmod..":stair_" .. newname .. "_wall_half_inverted")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_half", newmod..":stair_" .. newname .. "_half")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_half_inverted", newmod..":stair_" .. newname .. "_half_inverted")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_right_half", newmod..":stair_" .. newname .. "_right_half")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_right_half_inverted", newmod..":stair_" .. newname .. "_right_half_inverted")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half", newmod..":stair_" .. newname .. "_wall_half")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half_inverted", newmod..":stair_" .. newname .. "_wall_half_inverted")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_inner", newmod..":stair_" .. newname .. "_inner")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_inner_inverted", newmod..":stair_" .. newname .. "_inner_inverted")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_outer", newmod..":stair_" .. newname .. "_outer")
|
||||
minetest.register_alias(modname .. ":stair_" .. origname .. "_outer_inverted", newmod..":stair_" .. newname .. "_outer_inverted")
|
||||
minetest.register_alias(modname .. ":panel_" .. origname .. "_bottom", newmod..":panel_" .. newname .. "_bottom")
|
||||
minetest.register_alias(modname .. ":panel_" .. origname .. "_top", newmod..":panel_" .. newname .. "_top")
|
||||
minetest.register_alias(modname .. ":panel_" .. origname .. "_vertical", newmod..":panel_" .. newname .. "_vertical")
|
||||
minetest.register_alias(modname .. ":micro_" .. origname .. "_bottom", newmod..":micro_" .. newname .. "_bottom")
|
||||
minetest.register_alias(modname .. ":micro_" .. origname .. "_top", newmod..":micro_" .. newname .. "_top")
|
||||
function register_technic_stairs_alias(origmod, origname, newmod, newname)
|
||||
local func = minetest.register_alias
|
||||
local function remap(kind, suffix)
|
||||
-- Old: stairsplus:slab_concrete_wall
|
||||
-- New: technic:slab_concrete_wall
|
||||
func(("%s:%s_%s%s"):format(origmod, kind, origname, suffix),
|
||||
("%s:%s_%s%s"):format(newmod, kind, newname, suffix))
|
||||
end
|
||||
|
||||
-- Slabs
|
||||
remap("slab", "")
|
||||
remap("slab", "_inverted")
|
||||
remap("slab", "_wall")
|
||||
remap("slab", "_quarter")
|
||||
remap("slab", "_quarter_inverted")
|
||||
remap("slab", "_quarter_wall")
|
||||
remap("slab", "_three_quarter")
|
||||
remap("slab", "_three_quarter_inverted")
|
||||
remap("slab", "_three_quarter_wall")
|
||||
|
||||
-- Stairs
|
||||
remap("stair", "")
|
||||
remap("stair", "_inverted")
|
||||
remap("stair", "_wall")
|
||||
remap("stair", "_wall_half")
|
||||
remap("stair", "_wall_half_inverted")
|
||||
remap("stair", "_half")
|
||||
remap("stair", "_half_inverted")
|
||||
remap("stair", "_right_half")
|
||||
remap("stair", "_right_half_inverted")
|
||||
remap("stair", "_inner")
|
||||
remap("stair", "_inner_inverted")
|
||||
remap("stair", "_outer")
|
||||
remap("stair", "_outer_inverted")
|
||||
|
||||
-- Other
|
||||
remap("panel", "_bottom")
|
||||
remap("panel", "_top")
|
||||
remap("panel", "_vertical")
|
||||
remap("micro", "_bottom")
|
||||
remap("micro", "_top")
|
||||
end
|
||||
|
||||
register_technic_stairs_alias("stairsplus", "concrete", "technic", "concrete")
|
||||
|
369
manual.md
369
manual.md
@ -12,16 +12,16 @@ Documentation of the mod dependencies can be found here:
|
||||
* [Moreores Forum Post](https://forum.minetest.net/viewtopic.php?t=549)
|
||||
* [Basic materials Repository](https://gitlab.com/VanessaE/basic_materials)
|
||||
|
||||
## Recipes
|
||||
## 1.0 Recipes
|
||||
|
||||
Recipes for items registered by technic are not specifically documented here.
|
||||
Please consult a craft guide mod to look up the recipes in-game.
|
||||
|
||||
**Recommended mod:** [Unified Inventory](https://github.com/minetest-mods/unified_inventory)
|
||||
|
||||
## Substances
|
||||
## 2.0 Substances
|
||||
|
||||
### Ores
|
||||
### 2.1 Ores
|
||||
|
||||
Technic registers a few ores which are needed to craft machines or items.
|
||||
Each ore type is found at a specific range of elevations so you will
|
||||
@ -59,14 +59,14 @@ of its usage, so you will usually have a surplus of it.
|
||||
#### Zinc
|
||||
Use: brass
|
||||
|
||||
Depth: 2m, more commonly below -32m
|
||||
Generated below: 2m, more commonly below -32m
|
||||
|
||||
Zinc only has a few uses but is a common metal.
|
||||
|
||||
#### Chromium
|
||||
Use: stainless steel
|
||||
|
||||
Depth: -100m, more commonly below -200m
|
||||
Generated below: -100m, more commonly below -200m
|
||||
|
||||
#### Uranium
|
||||
Use: nuclear reactor fuel
|
||||
@ -82,14 +82,14 @@ Keep a safety distance of a meter to avoid being harmed by radiation.
|
||||
#### Silver ²
|
||||
Use: conductors
|
||||
|
||||
Depth: -2m, evenly common
|
||||
Generated below: -2m, evenly common
|
||||
|
||||
Silver is a semi-precious metal and is the best conductor of all the pure elements.
|
||||
|
||||
#### Gold ¹
|
||||
Use: various
|
||||
|
||||
Depth: -64m, more commonly below -256m
|
||||
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.
|
||||
@ -97,7 +97,7 @@ its combination of good conductivity and corrosion resistance.
|
||||
#### Mithril ²
|
||||
Use: chests
|
||||
|
||||
Depth: -512m, evenly common
|
||||
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.
|
||||
@ -114,7 +114,7 @@ Use: mainly for cutting machines
|
||||
Diamond is a precious gemstone. It is used moderately, mainly for reasons
|
||||
connected to its extreme hardness.
|
||||
|
||||
### Rocks
|
||||
### 2.2 Rocks
|
||||
|
||||
This section describes the rock types added by technic. Further rock types
|
||||
are supported by technic machines. These can be processed using the grinder:
|
||||
@ -136,7 +136,7 @@ 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.
|
||||
|
||||
### Rubber
|
||||
### 2.3 Rubber
|
||||
Rubber is a biologically-derived material that has industrial uses due
|
||||
to its electrical resistivity and its impermeability. In technic, it
|
||||
is used in a few recipes, and it must be acquired by tapping rubber trees.
|
||||
@ -150,7 +150,7 @@ observed by its appearance.
|
||||
|
||||
To obtain rubber from latex, alloy latex with coal dust.
|
||||
|
||||
### Metals
|
||||
## 3.0 Metal processing
|
||||
Generally, each metal can exist in five forms:
|
||||
|
||||
* ore -> stone containing the lump
|
||||
@ -162,7 +162,7 @@ Generally, each metal can exist in five forms:
|
||||
Metals can be converted between dust, ingot and block, but can't be converted
|
||||
from them back to ore or lump forms.
|
||||
|
||||
#### Grinding
|
||||
### Grinding
|
||||
Ores can be processed as follows:
|
||||
|
||||
* ore -> lump (digging) -> ingot (melting)
|
||||
@ -171,121 +171,59 @@ Ores can be processed as follows:
|
||||
At the expense of some energy consumption, the grinder can extract more material
|
||||
from the lump, resulting in 2x dust which can be melted to two ingots in total.
|
||||
|
||||
#### Alloying
|
||||
Alloying recipes in which a metal is the base ingredient, to produce a
|
||||
metal alloy, always come in two forms, using the metal either as dust
|
||||
or as an ingot. If the secondary ingredient is also a metal, it must
|
||||
be supplied in the same form as the base ingredient. The output alloy
|
||||
is also returned in the same form.
|
||||
### Alloying
|
||||
Input: two ingredients of the same form - lump or dust
|
||||
|
||||
Example: 2x copper ingots + zinc ingot -> 3x brass ingot (alloying)
|
||||
Output: resulting alloy, as an ingot
|
||||
|
||||
The same will also work for dust ingredients, resulting in brass dist.
|
||||
Example: 2x copper ingots + 1x zinc ingot -> 3x brass ingot (alloying)
|
||||
|
||||
### iron and its alloys ###
|
||||
Note that grinding before alloying is the preferred method to gain more output.
|
||||
|
||||
Iron forms several important alloys. In real-life history, iron was the
|
||||
second metal to be used as the base component of deliberately-constructed
|
||||
alloys (the first was copper), and it was the first metal whose working
|
||||
required processes of any metallurgical sophistication. The game
|
||||
mechanics around iron broadly imitate the historical progression of
|
||||
processes around it, rather than the less-varied modern processes.
|
||||
#### iron and its alloys
|
||||
|
||||
The two-component alloying system of iron with carbon is of huge
|
||||
importance, both in the game and in real life. The basic Minetest game
|
||||
doesn't distinguish between these pure iron and these alloys at all,
|
||||
but technic introduces a distinction based on the carbon content, and
|
||||
renames some items of the basic game accordingly.
|
||||
Historically iron was the first metal whose working required processes of any
|
||||
metallurgical sophistication. The mod's mechanics around iron broadly imitate
|
||||
the historical progression of processes around it to get more variety.
|
||||
|
||||
The iron/carbon spectrum is represented in the game by three metal
|
||||
substances: wrought iron, carbon steel, and cast iron. Wrought iron
|
||||
has low carbon content (less than 0.25%), resists shattering, and
|
||||
is easily welded, but is relatively soft and susceptible to rusting.
|
||||
In real-life history it was used for rails, gates, chains, wire, pipes,
|
||||
fasteners, and other purposes. Cast iron has high carbon content
|
||||
(2.1% to 4%), is especially hard, and resists corrosion, but is
|
||||
relatively brittle, and difficult to work. Historically it was used
|
||||
to build large structures such as bridges, and for cannons, cookware,
|
||||
and engine cylinders. Carbon steel has medium carbon content (0.25%
|
||||
to 2.1%), and intermediate properties: moderately hard and also tough,
|
||||
somewhat resistant to corrosion. In real life it is now used for most
|
||||
of the purposes previously satisfied by wrought iron and many of those
|
||||
of cast iron, but has historically been especially important for its
|
||||
use in swords, armor, skyscrapers, large bridges, and machines.
|
||||
Notable alloys:
|
||||
|
||||
In real-life history, the first form of iron to be refined was
|
||||
wrought iron, which is nearly pure iron, having low carbon content.
|
||||
It was produced from ore by a low-temperature furnace process (the
|
||||
"bloomery") in which the ore/iron remains solid and impurities (slag)
|
||||
are progressively removed by hammering ("working", hence "wrought").
|
||||
This began in the middle East, around 1800 BCE.
|
||||
* Wrought iron: <0.25% carbon
|
||||
* Resists shattering but is relatively soft.
|
||||
* Known since: 1800 BC (approx.)
|
||||
* Cast iron: 2.1% to 4% carbon.
|
||||
* Especially hard and rather corrosion-resistant
|
||||
* Known since: 1200 BC (approx.)
|
||||
* Carbon steel: 0.25% to 2.1% carbon.
|
||||
* Intermediate of the two above.
|
||||
* Known since: 1600 AD (approx.)
|
||||
|
||||
Historically, the next forms of iron to be refined were those of high
|
||||
carbon content. This was the result of the development of a more
|
||||
sophisticated kind of furnace, the blast furnace, capable of reaching
|
||||
higher temperatures. The real advantage of the blast furnace is that it
|
||||
melts the metal, allowing it to be cast straight into a shape supplied by
|
||||
a mould, rather than having to be gradually beaten into the desired shape.
|
||||
A side effect of the blast furnace is that carbon from the furnace's fuel
|
||||
is unavoidably incorporated into the metal. Normally iron is processed
|
||||
twice through the blast furnace: once producing "pig iron", which has
|
||||
very high carbon content and lots of impurities but lower melting point,
|
||||
casting it into rough ingots, then remelting the pig iron and casting it
|
||||
into the final moulds. The result is called "cast iron". Pig iron was
|
||||
first produced in China around 1200 BCE, and cast iron later in the 5th
|
||||
century BCE. Incidentally, the Chinese did not have the bloomery process,
|
||||
so this was their first iron refining process, and, unlike the rest of
|
||||
the world, their first wrought iron was made from pig iron rather than
|
||||
directly from ore.
|
||||
Technic introduces a distinction based on the carbon content, and renames some
|
||||
items of the basic game accordingly. Iron and Steel are now distinguished.
|
||||
|
||||
Carbon steel, with intermediate carbon content, was developed much later,
|
||||
in Europe in the 17th century CE. It required a more sophisticated
|
||||
process, because the blast furnace made it extremely difficult to achieve
|
||||
a controlled carbon content. Tweaks of the blast furnace would sometimes
|
||||
produce an intermediate carbon content by luck, but the first processes to
|
||||
reliably produce steel were based on removing almost all the carbon from
|
||||
pig iron and then explicitly mixing a controlled amount of carbon back in.
|
||||
Notable references:
|
||||
|
||||
In the game, the bloomery process is represented by ordinary cooking
|
||||
or grinding of an iron lump. The lump represents unprocessed ore,
|
||||
and is identified only as "iron", not specifically as wrought iron.
|
||||
This standard refining process produces dust or an ingot which is
|
||||
specifically identified as wrought iron. Thus the standard refining
|
||||
process produces the (nearly) pure metal.
|
||||
* https://en.wikipedia.org/wiki/Iron
|
||||
* https://en.wikipedia.org/wiki/Stainless_steel
|
||||
* ... plus many more.
|
||||
|
||||
Cast iron is trickier. You might expect from the real-life notes above
|
||||
that cooking an iron lump (representing ore) would produce pig iron that
|
||||
can then be cooked again to produce cast iron. This is kind of the case,
|
||||
but not exactly, because as already noted cooking an iron lump produces
|
||||
wrought iron. The game doesn't distinguish between low-temperature
|
||||
and high-temperature cooking processes: the same furnace is used not
|
||||
just to cast all kinds of metal but also to cook food. So there is no
|
||||
distinction between cooking processes to produce distinct wrought iron
|
||||
and pig iron. But repeated cooking *is* available as a game mechanic,
|
||||
and is indeed used to produce cast iron: re-cooking a wrought iron ingot
|
||||
produces a cast iron ingot. So pig iron isn't represented in the game as
|
||||
a distinct item; instead wrought iron stands in for pig iron in addition
|
||||
to its realistic uses as wrought iron.
|
||||
Processes:
|
||||
|
||||
Carbon steel is produced by a more regular in-game process: alloying
|
||||
wrought iron with coal dust (which is essentially carbon). This bears
|
||||
a fair resemblance to the historical development of carbon steel.
|
||||
This alloying recipe is relatively time-consuming for the amount of
|
||||
material processed, when compared against other alloying recipes, and
|
||||
carbon steel is heavily used, so it is wise to alloy it in advance,
|
||||
when you're not waiting for it.
|
||||
* Iron -> Wrought iron (melting)
|
||||
* Wrought iron -> Cast iron (melting)
|
||||
* Wrought iron + coal dust -> Carbon steel (alloying)
|
||||
* Carbon steel + coal dust -> Cast iron (alloying)
|
||||
* Carbon steel + chromium -> Stainless steel (alloying)
|
||||
|
||||
There are additional recipes that permit all three of these types of iron
|
||||
to be converted into each other. Alloying carbon steel again with coal
|
||||
dust produces cast iron, with its higher carbon content. Cooking carbon
|
||||
steel or cast iron produces wrought iron, in an abbreviated form of the
|
||||
bloomery process.
|
||||
Reversible processes:
|
||||
|
||||
There's one more iron alloy in the game: stainless steel. It is managed
|
||||
in a completely regular manner, created by alloying carbon steel with
|
||||
chromium.
|
||||
* Cast iron -> Wrought iron (melting)
|
||||
* Carbon steel -> Wrought iron (melting)
|
||||
|
||||
### uranium enrichment ###
|
||||
Check your preferred crafting guide for more information.
|
||||
|
||||
|
||||
### Uranium enrichment
|
||||
|
||||
When uranium is to be used to fuel a nuclear reactor, it is not
|
||||
sufficient to merely isolate and refine uranium metal. It is necessary
|
||||
@ -460,35 +398,15 @@ a post and adjacent concrete block.
|
||||
industrial processes
|
||||
--------------------
|
||||
|
||||
### alloying ###
|
||||
### Alloying
|
||||
|
||||
In technic, alloying is a way of combining items to create other items,
|
||||
distinct from standard crafting. Alloying always uses inputs of exactly
|
||||
two distinct types, and produces a single output. Like cooking, which
|
||||
takes a single input, it is performed using a powered machine, known
|
||||
generically as an "alloy furnace". An alloy furnace always has two
|
||||
input slots, and it doesn't matter which way round the two ingredients
|
||||
are placed in the slots. Many alloying recipes require one or both
|
||||
slots to contain a stack of more than one of the ingredient item: the
|
||||
quantity required of each ingredient is part of the recipe.
|
||||
In Technic, alloying is a way of combining items to create other items,
|
||||
distinct from standard crafting. Alloying always uses inputs of exactly
|
||||
two distinct types, and produces a single output.
|
||||
|
||||
As with the furnaces used for cooking, there are multiple kinds of alloy
|
||||
furnace, powered in different ways. The most-used alloy furnaces are
|
||||
electrically powered. There is also an alloy furnace that is powered
|
||||
by directly burning fuel, just like the basic cooking furnace. Building
|
||||
almost any electrical machine, including the electrically-powered alloy
|
||||
furnaces, requires a machine casing component, one ingredient of which
|
||||
is brass, an alloy. It is therefore necessary to use the fuel-fired
|
||||
alloy furnace in the early part of the game, on the way to building
|
||||
electrical machinery.
|
||||
Check your preferred crafting guide for more information.
|
||||
|
||||
Alloying recipes are mainly concerned with metals. These recipes
|
||||
combine a base metal with some other element, most often another metal,
|
||||
to produce a new metal. This is discussed in the section on metal.
|
||||
There are also a few alloying recipes in which the base ingredient is
|
||||
non-metallic, such as the recipe for the silicon wafer.
|
||||
|
||||
### grinding, extracting, and compressing ###
|
||||
### Grinding, extracting, and compressing
|
||||
|
||||
Grinding, extracting, and compressing are three distinct, but very
|
||||
similar, ways of converting one item into another. They are all quite
|
||||
@ -562,57 +480,17 @@ metal alloys. This can only be done using the dust form of the alloy.
|
||||
It recovers both components of binary metal/metal alloys. It can't
|
||||
recover the carbon from steel or cast iron.
|
||||
|
||||
chests
|
||||
Chests
|
||||
------
|
||||
|
||||
The technic mod replaces the basic Minetest game's single type of
|
||||
chest with a range of chests that have different sizes and features.
|
||||
The chest types are identified by the materials from which they are made;
|
||||
the better chests are made from more exotic materials. The chest types
|
||||
form a linear sequence, each being (with one exception noted below)
|
||||
strictly more powerful than the preceding one. The sequence begins with
|
||||
the wooden chest from the basic game, and each later chest type is built
|
||||
by upgrading a chest of the preceding type. The chest types are:
|
||||
See [GitHub Wiki / Chests](https://github.com/minetest-mods/technic/wiki/Chests)
|
||||
|
||||
1. wooden chest: 8×4 (32) slots
|
||||
2. iron chest: 9×5 (45) slots
|
||||
3. copper chest: 12×5 (60) slots
|
||||
4. silver chest: 12×6 (72) slots
|
||||
5. gold chest: 15×6 (90) slots
|
||||
6. mithril chest: 15×6 (90) slots
|
||||
Features of extended chests:
|
||||
|
||||
The iron and later chests have the ability to sort their contents,
|
||||
when commanded by a button in their interaction forms. Item types are
|
||||
sorted in the same order used in the unified\_inventory craft guide.
|
||||
The copper and later chests also have an auto-sorting facility that can
|
||||
be enabled from the interaction form. An auto-sorting chest automatically
|
||||
sorts its contents whenever a player closes the chest. The contents will
|
||||
then usually be in a sorted state when the chest is opened, but may not
|
||||
be if pneumatic tubes have operated on the chest while it was closed,
|
||||
or if two players have the chest open simultaneously.
|
||||
* Larger storage space
|
||||
* Labelling
|
||||
* Advanced item sorting
|
||||
|
||||
The silver and gold chests, but not the mithril chest, have a built-in
|
||||
sign-like capability. They can be given a textual label, which will
|
||||
be visible when hovering over the chest. The gold chest, but again not
|
||||
the mithril chest, can be further labelled with a colored patch that is
|
||||
visible from a moderate distance.
|
||||
|
||||
The mithril chest is currently an exception to the upgrading system.
|
||||
It has only as many inventory slots as the preceding (gold) type, and has
|
||||
fewer of the features. It has no feature that other chests don't have:
|
||||
it is strictly weaker than the gold chest. It is planned that in the
|
||||
future it will acquire some unique features, but for now the only reason
|
||||
to use it is aesthetic.
|
||||
|
||||
The size of the largest chests is dictated by the maximum size
|
||||
of interaction form that the game engine can successfully display.
|
||||
If in the future the engine becomes capable of handling larger forms,
|
||||
by scaling them to fit the screen, the sequence of chest sizes will
|
||||
likely be revised.
|
||||
|
||||
As with the chest of the basic Minetest game, each chest type comes
|
||||
in both locked and unlocked flavors. All of the chests work with the
|
||||
pneumatic tubes of the pipeworks mod.
|
||||
|
||||
radioactivity
|
||||
-------------
|
||||
@ -750,115 +628,44 @@ so the positioning of holes in each layer must still be considered.
|
||||
Tricky shine paths can also be addressed by just keeping players out of
|
||||
the dangerous area.
|
||||
|
||||
electrical power
|
||||
----------------
|
||||
## Electrical power
|
||||
|
||||
Most machines in technic are electrically powered. To operate them it is
|
||||
necessary to construct an electrical power network. The network links
|
||||
together power generators and power-consuming machines, connecting them
|
||||
using power cables.
|
||||
Electrical networks in Technic are defined by a single tier (see below)
|
||||
and consist of:
|
||||
|
||||
There are three tiers of electrical networking: low voltage (LV),
|
||||
medium voltage (MV), and high voltage (HV). Each network must operate
|
||||
at a single voltage, and most electrical items are specific to a single
|
||||
voltage. Generally, the machines of higher tiers are more powerful,
|
||||
but consume more energy and are more expensive to build, than machines
|
||||
of lower tiers. It is normal to build networks of all three tiers,
|
||||
in ascending order as one progresses through the game, but it is not
|
||||
strictly necessary to do this. Building HV equipment requires some parts
|
||||
that can only be manufactured using electrical machines, either LV or MV,
|
||||
so it is not possible to build an HV network first, but it is possible
|
||||
to skip either LV or MV on the way to HV.
|
||||
* 1x Switching Station (central management unit)
|
||||
* Any further stations are disabled automatically
|
||||
* Electricity producers (PR)
|
||||
* Electricity consumers/receivers (RE)
|
||||
* Accumulators/batteries (BA)
|
||||
|
||||
Each voltage has its own cable type, with distinctive insulation. Cable
|
||||
segments connect to each other and to compatible machines automatically.
|
||||
Incompatible electrical items don't connect. All non-cable electrical
|
||||
items must be connected via cable: they don't connect directly to each
|
||||
other. Most electrical items can connect to cables in any direction,
|
||||
but there are a couple of important exceptions noted below.
|
||||
### Tiers
|
||||
|
||||
To be useful, an electrical network must connect at least one power
|
||||
generator to at least one power-consuming machine. In addition to these
|
||||
items, the network must have a "switching station" in order to operate:
|
||||
no energy will flow without one. Unlike most electrical items, the
|
||||
switching station is not voltage-specific: the same item will manage
|
||||
a network of any tier. However, also unlike most electrical items,
|
||||
it is picky about the direction in which it is connected to the cable:
|
||||
the cable must be directly below the switching station.
|
||||
* LV: Low Voltage. Low material costs but is slower.
|
||||
* MV: Medium Voltage. Higher processing speed.
|
||||
* HV: High Voltage. High material costs but is the fastest.
|
||||
|
||||
Hovering over a network's switching station will show the aggregate energy
|
||||
supply and demand, which is useful for troubleshooting. Electrical energy
|
||||
is measured in "EU", and power (energy flow) in EU per second (EU/s).
|
||||
Energy is shifted around a network instantaneously once per second.
|
||||
Tiers can be converted from one to another using the Supply Converter node.
|
||||
Its top connects to the input, the bottom to the output network. Configure
|
||||
the input power by right-clicking it.
|
||||
|
||||
In a simple network with only generators and consumers, if total
|
||||
demand exceeds total supply then no energy will flow, the machines
|
||||
will do nothing, and the generators' output will be lost. To handle
|
||||
this situation, it is recommended to add a battery box to the network.
|
||||
A battery box will store generated energy, and when enough has been
|
||||
stored to run the consumers for one second it will deliver it to the
|
||||
consumers, letting them run part-time. It also stores spare energy
|
||||
when supply exceeds demand, to let consumers run full-time when their
|
||||
demand occasionally peaks above the supply. More battery boxes can
|
||||
be added to cope with larger periods of mismatched supply and demand,
|
||||
such as those resulting from using solar generators (which only produce
|
||||
energy in the daytime).
|
||||
### Machine upgrade slots
|
||||
|
||||
When there are electrical networks of multiple tiers, it can be appealing
|
||||
to generate energy on one tier and transfer it to another. The most
|
||||
direct way to do this is with the "supply converter", which can be
|
||||
directly wired into two networks. It is another tier-independent item,
|
||||
and also particular about the direction of cable connections: it must
|
||||
have the cable of one network directly above, and the cable of another
|
||||
network directly below. The supply converter demands 10000 EU/s from
|
||||
the network above, and when this network gives it power it supplies 9000
|
||||
EU/s to the network below. Thus it is only 90% efficient, unlike most of
|
||||
the electrical system which is 100% efficient in moving energy around.
|
||||
To transfer more than 10000 EU/s between networks, connect multiple
|
||||
supply converters in parallel.
|
||||
Generally, machines of MV and HV tiers have two upgrade slots.
|
||||
Only specific items will have any upgrading effect. The occupied slots do
|
||||
count, but not the actual stack size.
|
||||
|
||||
powered machines
|
||||
----------------
|
||||
**Type 1: Energy upgrade**
|
||||
|
||||
### powered machine tiers ###
|
||||
Consists of any battery item. Reduces the machine's power consumption
|
||||
regardless the charge of the item.
|
||||
|
||||
Each powered machine takes its power in some specific form, being
|
||||
either fuel-fired (burning fuel directly) or electrically powered at
|
||||
some specific voltage. There is a general progression through the
|
||||
game from using fuel-fired machines to electrical machines, and to
|
||||
higher electrical voltages. The most important kinds of machine come
|
||||
in multiple variants that are powered in different ways, so the earlier
|
||||
ones can be superseded. However, some machines are only available for
|
||||
a specific power tier, so the tier can't be entirely superseded.
|
||||
**Type 2: Tube upgrade**
|
||||
|
||||
### powered machine upgrades ###
|
||||
Consists of a control logic unit item. Ejects processed items into pneumatic
|
||||
tubes for quicker processing.
|
||||
|
||||
Some machines have inventory slots that are used to upgrade them in
|
||||
some way. Generally, machines of MV and HV tiers have two upgrade slots,
|
||||
and machines of lower tiers (fuel-fired and LV) do not. Any item can
|
||||
be placed in an upgrade slot, but only specific items will have any
|
||||
upgrading effect. It is possible to have multiple upgrades of the same
|
||||
type, but this can't be achieved by stacking more than one upgrade item
|
||||
in one slot: it is necessary to put the same kind of item in more than one
|
||||
upgrade slot. The ability to upgrade machines is therefore very limited.
|
||||
Two kinds of upgrade are currently possible: an energy upgrade and a
|
||||
tube upgrade.
|
||||
|
||||
An energy upgrade consists of a battery item, the same kind of battery
|
||||
that serves as a mobile energy store. The effect of an energy upgrade
|
||||
is to improve in some way the machine's use of electrical energy, most
|
||||
often by making it use less energy. The upgrade effect has no relation
|
||||
to energy stored in the battery: the battery's charge level is irrelevant
|
||||
and will not be affected.
|
||||
|
||||
A tube upgrade consists of a control logic unit item. The effect of a
|
||||
tube upgrade is to make the machine able, or more able, to eject items
|
||||
it has finished with into pneumatic tubes. The machines that can take
|
||||
this kind of upgrade are in any case capable of accepting inputs from
|
||||
pneumatic tubes. These upgrades are essential in using powered machines
|
||||
as components in larger automated systems.
|
||||
|
||||
### tubes with powered machines ###
|
||||
### Machines + Tubes (pipeworks)
|
||||
|
||||
Generally, powered machines of MV and HV tiers can work with pneumatic
|
||||
tubes, and those of lower tiers cannot. (As an exception, the fuel-fired
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
This file documents the functions within the technic modpack for use in mods.
|
||||
|
||||
[Switch to plaintext format](https://raw.githubusercontent.com/minetest-mods/technic/master/technic/doc/api.md)
|
||||
|
||||
**Undocumented API may change at any time.**
|
||||
|
||||
|
||||
## Tiers
|
||||
Tier are network types. List of pre-registered tiers:
|
||||
@ -37,33 +41,84 @@ Available functions:
|
||||
The machine type indicates the direction of power flow.
|
||||
List of pre-registered machine types:
|
||||
|
||||
* `technic.receiver = "RE"` e.g. grinder
|
||||
* `technic.producer = "PR"` e.g. solar panel
|
||||
* `technic.receiver = "RE"`: consumes energy. e.g. grinder
|
||||
* `technic.producer = "PR"`: provides energy. e.g. solar panel
|
||||
* `technic.producer_receiver = "PR_RE"` supply converter
|
||||
* `technic.battery = "BA"` e.g. LV battery box
|
||||
* `technic.battery = "BA"`: stores energy. e.g. LV battery box
|
||||
|
||||
Available functions:
|
||||
|
||||
* `technic.register_base_machine(data)`
|
||||
* Registers a new node and defines the underlying machine behaviour. `data` fields:
|
||||
* `tier`: string, see #Tiers
|
||||
* `typename`: string, equivalent to the processing type registered
|
||||
by `technic.register_recipe`. Examples: `"cooking"` `"alloy"`
|
||||
* `machine_name`: string, node name
|
||||
* `machine_desc`: string, node description
|
||||
* `demand`: table, EU consumption values for each upgrade level.
|
||||
Up to three indices. Index 1 == no upgrade. Example: `{3000, 2000, 1000}`.
|
||||
* `upgrade`: (boolean), whether to add upgrade slots
|
||||
* `modname`: (string), mod origin
|
||||
* `tube`: (boolean), whether the machine has Pipeworks connectivity
|
||||
* `can_insert`: (func), see Pipeworks documentation
|
||||
* Accepts all inputs by default, if `tube = 1`
|
||||
* See also: `technic.can_insert_unique_stack`
|
||||
* `insert_object`: (func), see Pipeworks documentation
|
||||
* Accepts all inputs by default, if `tube = 1`
|
||||
* See also: `technic.insert_object_unique_stack`
|
||||
* `connect_sides`: (table), see Lua API documentation. Defaults to all directions but front.
|
||||
* `technic.register_machine(tier, nodename, machine_type)`
|
||||
* Register an existing node as machine, bound to the network tier
|
||||
* `tier`: see `register_tier`
|
||||
* `tier`: string, see #Tiers
|
||||
* `nodename`: string, node name
|
||||
* `machine_type`: string, following options are possible:
|
||||
* `"RE"`: Receiver
|
||||
* `"PR"`: Producer
|
||||
* `"BA"`: Battery, energy storage
|
||||
* `technic.receiver = "RE"`: Consumes energy
|
||||
* `technic.producer = "PR"`: Provides energy
|
||||
* `technic.battery = "BA"`: Energy storage
|
||||
* See also `Machine types`
|
||||
|
||||
Functions to use for callbacks:
|
||||
Callbacks for pipeworks item transfer:
|
||||
|
||||
* `technic.can_insert_unique_stack(pos, node, stack, direction)`
|
||||
* `technic.insert_object_unique_stack(pos, node, stack, direction)`
|
||||
* Functions for the parameters `can_insert` and `insert_object` to avoid
|
||||
filling multiple inventory slots with same type of item.
|
||||
|
||||
### Specific machines
|
||||
* `technic.register_solar_array(data)`
|
||||
* data is a table (TODO)
|
||||
### Recipes
|
||||
|
||||
* `technic.register_recipe_type(typename, recipedef)`
|
||||
* Registers a new recipe type used for machine processing
|
||||
* `typename`: string, name of the recipe type
|
||||
* Fields of `recipedef`:
|
||||
* `description`: string, descriptor of the recipe type
|
||||
* `input_size`: (numeric), count of input ItemStacks. default 1
|
||||
* `output_size`: (numeric), count of output ItemStacks. default 1
|
||||
* `technic.register_recipe(recipe)`
|
||||
* Registers a individual input/output recipe. Fields of `recipe`:
|
||||
* `input`: table, integer-indexed list of input ItemStacks.
|
||||
* `output`: table/ItemStack, single output or list of output ItemStacks.
|
||||
* `time`: numeric, process time in seconds.
|
||||
* `technic.get_recipe(typename, items)`
|
||||
* `typename`: string, see `technic.register_recipe_type`
|
||||
* `items`: table, integer-indexed list of input ItemStacks.
|
||||
* Returns: `recipe` table on success, `nil` otherwise
|
||||
|
||||
|
||||
The following functions can be used to register recipes for
|
||||
a specific machine type:
|
||||
|
||||
* Centrifuge
|
||||
* `technic.register_separating_recipe(recipe)`
|
||||
* Compressor
|
||||
* `technic.register_compressor_recipe(recipe)`
|
||||
* Furnaces (electric, normal)
|
||||
* `minetest.register_recipe(recipe)`
|
||||
* Extractor
|
||||
* `technic.register_extractor_recipe(recipe)`
|
||||
* Freezer
|
||||
* `technic.register_freezer_recipe(recipe)`
|
||||
* Grinder
|
||||
* `technic.register_grinder_recipe(recipe)`
|
||||
|
||||
|
||||
## Tools
|
||||
@ -132,7 +187,7 @@ Groups:
|
||||
|
||||
Additional definition fields:
|
||||
|
||||
* `wear_represents = "string"`
|
||||
* `<itemdef>.wear_represents = "string"`
|
||||
* Specifies how the tool wear level is handled. Available modes:
|
||||
* `"mechanical_wear"`: represents physical damage
|
||||
* `"technic_RE_charge"`: represents electrical charge
|
||||
@ -140,10 +195,22 @@ Additional definition fields:
|
||||
* This callback is used to update the node.
|
||||
Modders have to manually change the information about supply etc. in the
|
||||
node metadata.
|
||||
* Technic-registered machines use this callback by default.
|
||||
* `<itemdef>.technic_disabled_machine_name = "string"`
|
||||
* Specifies the machine's node name to use when it's not connected connected to a network
|
||||
* `<itemdef>.technic_on_disable = function(pos, node) ...`
|
||||
* This callback is run when the machine is no longer connected to a technic-powered network.
|
||||
* `<itemdef>.technic_get_charge = function(itemstack) ...`
|
||||
* Optional callback to overwrite the default charge behaviour.
|
||||
* `itemstack`: ItemStack, the tool to analyse
|
||||
* Return values:
|
||||
* `charge`: Electrical charge of the tool
|
||||
* `max_charge`: Upper charge limit
|
||||
* Etc. `local charge, maxcharge = itemdef.technic_get_charge(itemstack)`
|
||||
* `<itemdef>.technic_set_charge = function(itemstack, charge) ...`
|
||||
* Optional callback to overwrite the default charge behaviour.
|
||||
* `itemstack`: ItemStack, the tool to update
|
||||
* `charge`: numeric, value between `0` and `max_charge`
|
||||
|
||||
|
||||
## Node Metadata fields
|
||||
@ -165,33 +232,30 @@ data:
|
||||
multiple tiers (or networks).
|
||||
|
||||
|
||||
## Switching Station mechanics
|
||||
## Manual: Network basics
|
||||
|
||||
The switching station is the center of all power distribution on an electric
|
||||
network.
|
||||
network. This node is used to calculate the power supply of the network and
|
||||
to distribute the power across nodes.
|
||||
|
||||
The station collects power from sources (PR), distributes it to sinks (RE),
|
||||
and uses the excess/shortfall to charge and discharge batteries (BA).
|
||||
The switching station is the center of all electricity distribution. It collects
|
||||
power from sources (PR), distributes it to sinks (RE), and uses the
|
||||
excess/shortfall to charge and discharge batteries (BA).
|
||||
|
||||
For now, all supply and demand values are expressed in kW.
|
||||
As a thumb of rule, "EU" (energy unit) values are expressed in kW.
|
||||
|
||||
It works like this:
|
||||
All PR,BA,RE nodes are indexed and tagged with the switching station.
|
||||
The tagging is a workaround to allow more stations to be built without allowing
|
||||
a cheat with duplicating power.
|
||||
All the RE nodes are queried for their current EU demand. Those which are off
|
||||
would require no or a small standby EU demand, while those which are on would
|
||||
require more.
|
||||
If the total demand is less than the available power they are all updated with
|
||||
the demand number.
|
||||
If any surplus exists from the PR nodes the batteries will be charged evenly
|
||||
with this.
|
||||
If the total demand requires draw on the batteries they will be discharged
|
||||
evenly.
|
||||
Network functionality:
|
||||
|
||||
If the total demand is more than the available power all RE nodes will be shut
|
||||
down. We have a brown-out situation.
|
||||
|
||||
Hence for now all the power distribution logic resides in this single node.
|
||||
1. All PR, BA, RE nodes are indexed and tagged with one switching station.
|
||||
The tagging is a workaround to allow more stations to be built without allowing
|
||||
a cheat with duplicating power.
|
||||
2. All the RE nodes are queried for their current EU demand.
|
||||
If the total demand is less than the available power they are all updated
|
||||
with the demand number.
|
||||
3. BA nodes are evenly charged from energy surplus.
|
||||
4. Excess power draw will discharge batteries evenly.
|
||||
5. If the total demand is more than the available power all RE nodes will be shut
|
||||
down. We have a brown-out situation.
|
||||
|
||||
## Deprecated functions
|
||||
|
||||
|
@ -1,7 +1,11 @@
|
||||
-- Minetest 0.4.7 mod: technic
|
||||
-- namespace: technic
|
||||
-- (c) 2012-2013 by RealBadAngel <mk@realbadangel.pl>
|
||||
|
||||
if not minetest.get_translator then
|
||||
error("[technic] Your Minetest version is no longer supported."
|
||||
.. " (version < 5.0.0)")
|
||||
end
|
||||
|
||||
local load_start = os.clock()
|
||||
|
||||
technic = rawget(_G, "technic") or {}
|
||||
@ -16,7 +20,17 @@ technic.modpath = modpath
|
||||
if rawget(_G, "intllib") then
|
||||
technic.getter = intllib.Getter()
|
||||
else
|
||||
technic.getter = function(s,a,...)if a==nil then return s end a={a,...}return s:gsub("(@?)@(%(?)(%d+)(%)?)",function(e,o,n,c)if e==""then return a[tonumber(n)]..(o==""and c or"")else return"@"..o..n..c end end) end
|
||||
-- Intllib copypasta: TODO replace with the client-side translation API
|
||||
technic.getter = function(s,a,...)
|
||||
if a==nil then return s end
|
||||
a={a,...}
|
||||
return s:gsub("(@?)@(%(?)(%d+)(%)?)", function(e,o,n,c)
|
||||
if e==""then
|
||||
return a[tonumber(n)]..(o==""and c or"")
|
||||
end
|
||||
return "@"..o..n..c
|
||||
end)
|
||||
end
|
||||
end
|
||||
local S = technic.getter
|
||||
|
||||
|
@ -112,10 +112,13 @@ local function set_forcefield_formspec(meta)
|
||||
else
|
||||
formspec = formspec.."button[0,1;5,1;mesecon_mode_0;"..S("Controlled by Mesecon Signal").."]"
|
||||
end
|
||||
-- TODO: String replacement with %s will stop working with client-side translations
|
||||
if meta:get_int("enabled") == 0 then
|
||||
formspec = formspec.."button[0,1.75;5,1;enable;"..S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
|
||||
formspec = formspec.."button[0,1.75;5,1;enable;"..
|
||||
S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
|
||||
else
|
||||
formspec = formspec.."button[0,1.75;5,1;disable;"..S("%s Enabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
|
||||
formspec = formspec.."button[0,1.75;5,1;disable;"..
|
||||
S("%s Enabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
|
||||
end
|
||||
meta:set_string("formspec", formspec)
|
||||
end
|
||||
|
@ -47,14 +47,19 @@ local function set_quarry_demand(meta)
|
||||
local radius = meta:get_int("size")
|
||||
local diameter = radius*2 + 1
|
||||
local machine_name = S("%s Quarry"):format("HV")
|
||||
if meta:get_int("enabled") == 0 or meta:get_int("purge_on") == 1 then
|
||||
meta:set_string("infotext", S(meta:get_int("purge_on") == 1 and "%s purging cache" or "%s Disabled"):format(machine_name))
|
||||
local do_purge = meta:get_int("purge_on") == 1
|
||||
if meta:get_int("enabled") == 0 or do_purge then
|
||||
local infotext = do_purge and
|
||||
S("%s purging cache") or S("%s Disabled")
|
||||
meta:set_string("infotext", infotext:format(machine_name))
|
||||
meta:set_int("HV_EU_demand", 0)
|
||||
elseif meta:get_int("dug") == diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) then
|
||||
meta:set_string("infotext", S("%s Finished"):format(machine_name))
|
||||
meta:set_int("HV_EU_demand", 0)
|
||||
else
|
||||
meta:set_string("infotext", S(meta:get_int("HV_EU_input") >= quarry_demand and "%s Active" or "%s Unpowered"):format(machine_name))
|
||||
local infotext = meta:get_int("HV_EU_input") >= quarry_demand
|
||||
and S("%s Active") or S("%s Unpowered")
|
||||
meta:set_string("infotext", infotext:format(machine_name))
|
||||
meta:set_int("HV_EU_demand", quarry_demand)
|
||||
end
|
||||
end
|
||||
|
@ -36,7 +36,8 @@ technic.register_inductive_machine = function(name)
|
||||
end
|
||||
|
||||
-- Appliances:
|
||||
-- has_supply: pos of supply node if the appliance has a power radiator near with sufficient power for the demand else ""
|
||||
-- has_supply: pos of supply node if the appliance has a power radiator near
|
||||
-- with sufficient power for the demand else ""
|
||||
-- EU_demand: The power demand of the device.
|
||||
-- EU_charge: Actual use. set to EU_demand if active==1
|
||||
-- active: set to 1 if the device is on
|
||||
|
@ -48,20 +48,23 @@ local function forceload_on(pos, meta)
|
||||
end
|
||||
|
||||
local function set_display(pos, meta)
|
||||
local ESC = minetest.formspec_escape
|
||||
meta:set_string("infotext", S(meta:get_int("enabled") ~= 0 and "%s Enabled" or "%s Disabled"):format(desc))
|
||||
meta:set_string("formspec",
|
||||
"size[5,3.5]"..
|
||||
"item_image[0,0;1,1;technic:admin_anchor]"..
|
||||
"label[1,0;"..minetest.formspec_escape(desc).."]"..
|
||||
"label[0,1;"..minetest.formspec_escape(S("Owner:").." "..meta:get_string("owner")).."]"..
|
||||
"label[1,0;"..ESC(desc).."]"..
|
||||
"label[0,1;"..ESC(S("Owner:").." "..meta:get_string("owner")).."]"..
|
||||
(meta:get_int("locked") == 0 and
|
||||
"button[3,1;2,1;lock;"..minetest.formspec_escape(S("Unlocked")).."]" or
|
||||
"button[3,1;2,1;unlock;"..minetest.formspec_escape(S("Locked")).."]")..
|
||||
"field[0.25,2.3;1,1;radius;"..minetest.formspec_escape(S("Radius:"))..";"..meta:get_int("radius").."]"..
|
||||
"button[3,1;2,1;lock;"..ESC(S("Unlocked")).."]" or
|
||||
"button[3,1;2,1;unlock;"..ESC(S("Locked")).."]")..
|
||||
"field[0.25,2.3;1,1;radius;"..ESC(S("Radius:"))..";"..meta:get_int("radius").."]"..
|
||||
(meta:get_int("enabled") == 0 and
|
||||
"button[3,2;2,1;enable;"..minetest.formspec_escape(S("Disabled")).."]" or
|
||||
"button[3,2;2,1;disable;"..minetest.formspec_escape(S("Enabled")).."]")..
|
||||
"label[0,3;"..minetest.formspec_escape(S("Keeping %d/%d map blocks loaded"):format(#currently_forceloaded_positions(meta), #compute_forceload_positions(pos, meta))).."]")
|
||||
"button[3,2;2,1;enable;"..ESC(S("Disabled")).."]" or
|
||||
"button[3,2;2,1;disable;"..ESC(S("Enabled")).."]")..
|
||||
"label[0,3;"..ESC(S("Keeping %d/%d map blocks loaded"):format(
|
||||
#currently_forceloaded_positions(meta), #compute_forceload_positions(pos, meta)
|
||||
)).."]")
|
||||
end
|
||||
|
||||
minetest.register_node("technic:admin_anchor", {
|
||||
@ -80,7 +83,8 @@ minetest.register_node("technic:admin_anchor", {
|
||||
end,
|
||||
can_dig = function (pos, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
return meta:get_int("locked") == 0 or (player and player:is_player() and player:get_player_name() == meta:get_string("owner"))
|
||||
return meta:get_int("locked") == 0 or
|
||||
(player and player:is_player() and player:get_player_name() == meta:get_string("owner"))
|
||||
end,
|
||||
on_destruct = function (pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
@ -99,7 +103,11 @@ minetest.register_node("technic:admin_anchor", {
|
||||
forceload_off(meta)
|
||||
if fields.disable then meta:set_int("enabled", 0) end
|
||||
if fields.enable then meta:set_int("enabled", 1) end
|
||||
if fields.radius and string.find(fields.radius, "^[0-9]+$") and tonumber(fields.radius) < 256 then meta:set_int("radius", fields.radius) end
|
||||
if fields.radius
|
||||
and string.find(fields.radius, "^[0-9]+$")
|
||||
and tonumber(fields.radius) < 256 then
|
||||
meta:set_int("radius", fields.radius)
|
||||
end
|
||||
if meta:get_int("enabled") ~= 0 then
|
||||
forceload_on(pos, meta)
|
||||
end
|
||||
|
@ -88,22 +88,22 @@ local function pos_in_list(l, pos)
|
||||
return false
|
||||
end
|
||||
|
||||
local function table_empty(table)
|
||||
for _, __ in pairs(table) do
|
||||
local function table_empty(what)
|
||||
for _ in pairs(what) do
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function add_table(table, toadd)
|
||||
local function add_table(what, toadd)
|
||||
local i = 1
|
||||
while true do
|
||||
local o = table[i]
|
||||
local o = what[i]
|
||||
if o == toadd then return end
|
||||
if o == nil then break end
|
||||
i = i + 1
|
||||
end
|
||||
table[i] = toadd
|
||||
what[i] = toadd
|
||||
end
|
||||
|
||||
local function move_nodes_vect(poslist, vect, must_not_move, owner)
|
||||
@ -398,20 +398,6 @@ minetest.register_entity("technic:frame_entity", {
|
||||
local pos = vector.round(self.object:getpos())
|
||||
frames_pos[pos_to_string(pos)] = node.name
|
||||
|
||||
local stack = ItemStack(node.name)
|
||||
local itemtable = stack:to_table()
|
||||
local itemname = nil
|
||||
|
||||
if itemtable then
|
||||
itemname = stack:to_table().name
|
||||
end
|
||||
|
||||
local item_texture = nil
|
||||
local item_type = ""
|
||||
if minetest.registered_items[itemname] then
|
||||
item_texture = minetest.registered_items[itemname].inventory_image
|
||||
item_type = minetest.registered_items[itemname].type
|
||||
end
|
||||
local prop = {
|
||||
is_visible = true,
|
||||
textures = { node.name },
|
||||
|
@ -304,9 +304,9 @@ function technic.register_battery_box(data)
|
||||
drop = "technic:"..ltier.."_battery_box0",
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local EU_upgrade, tube_upgrade = 0, 0
|
||||
local EU_upgrade, _ = 0
|
||||
if data.upgrade then
|
||||
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
|
||||
EU_upgrade, _ = technic.handle_machine_upgrades(meta)
|
||||
end
|
||||
local max_charge = data.max_charge * (1 + EU_upgrade / 10)
|
||||
local charge = meta:get_int("internal_EU_charge")
|
||||
@ -345,9 +345,9 @@ function technic.register_battery_box(data)
|
||||
meta = minetest.get_meta(pos)
|
||||
if not pipeworks.may_configure(pos, sender) then return end
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
local EU_upgrade, tube_upgrade = 0, 0
|
||||
local EU_upgrade, _ = 0
|
||||
if data.upgrade then
|
||||
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
|
||||
EU_upgrade, _ = technic.handle_machine_upgrades(meta)
|
||||
end
|
||||
local max_charge = data.max_charge * (1 + EU_upgrade / 10)
|
||||
local charge = meta:get_int("internal_EU_charge")
|
||||
@ -409,6 +409,30 @@ minetest.register_on_player_receive_fields(
|
||||
end
|
||||
)
|
||||
|
||||
local function default_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]
|
||||
end
|
||||
|
||||
local function default_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))
|
||||
end
|
||||
|
||||
function technic.charge_tools(meta, batt_charge, charge_step)
|
||||
local inv = meta:get_inventory()
|
||||
if inv:is_empty("src") then
|
||||
@ -416,18 +440,18 @@ function technic.charge_tools(meta, batt_charge, charge_step)
|
||||
end
|
||||
local src_stack = inv:get_stack("src", 1)
|
||||
|
||||
local tool_name = src_stack:get_name()
|
||||
if not technic.power_tools[tool_name] then
|
||||
-- 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
|
||||
|
||||
-- get tool charge
|
||||
local tool_charge, item_max_charge = technic_get_charge(src_stack)
|
||||
if item_max_charge==0 then
|
||||
return batt_charge, false
|
||||
end
|
||||
-- Set meta data for the tool if it didn't do it itself
|
||||
local src_meta = minetest.deserialize(src_stack:get_metadata()) or {}
|
||||
if not src_meta.charge then
|
||||
src_meta.charge = 0
|
||||
end
|
||||
|
||||
-- Do the charging
|
||||
local item_max_charge = technic.power_tools[tool_name]
|
||||
local tool_charge = src_meta.charge
|
||||
if tool_charge >= item_max_charge then
|
||||
return batt_charge, true
|
||||
elseif batt_charge <= 0 then
|
||||
@ -437,9 +461,7 @@ function technic.charge_tools(meta, batt_charge, charge_step)
|
||||
charge_step = math.min(charge_step, item_max_charge - tool_charge)
|
||||
tool_charge = tool_charge + charge_step
|
||||
batt_charge = batt_charge - charge_step
|
||||
technic.set_RE_wear(src_stack, tool_charge, item_max_charge)
|
||||
src_meta.charge = tool_charge
|
||||
src_stack:set_metadata(minetest.serialize(src_meta))
|
||||
technic_set_charge(src_stack, tool_charge)
|
||||
inv:set_stack("src", 1, src_stack)
|
||||
return batt_charge, (tool_charge == item_max_charge)
|
||||
end
|
||||
@ -450,21 +472,20 @@ function technic.discharge_tools(meta, batt_charge, charge_step, max_charge)
|
||||
if inv:is_empty("dst") then
|
||||
return batt_charge, false
|
||||
end
|
||||
local srcstack = inv:get_stack("dst", 1)
|
||||
local toolname = srcstack:get_name()
|
||||
if technic.power_tools[toolname] == nil then
|
||||
local src_stack = inv:get_stack("dst", 1)
|
||||
|
||||
-- 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
|
||||
|
||||
-- get tool charge
|
||||
local tool_charge, item_max_charge = technic_get_charge(src_stack)
|
||||
if item_max_charge==0 then
|
||||
return batt_charge, false
|
||||
end
|
||||
-- Set meta data for the tool if it didn't do it itself :-(
|
||||
local src_meta = minetest.deserialize(srcstack:get_metadata())
|
||||
src_meta = src_meta or {}
|
||||
if not src_meta.charge then
|
||||
src_meta.charge = 0
|
||||
end
|
||||
|
||||
-- Do the discharging
|
||||
local item_max_charge = technic.power_tools[toolname]
|
||||
local tool_charge = src_meta.charge
|
||||
if tool_charge <= 0 then
|
||||
return batt_charge, true
|
||||
elseif batt_charge >= max_charge then
|
||||
@ -474,10 +495,8 @@ function technic.discharge_tools(meta, batt_charge, charge_step, max_charge)
|
||||
charge_step = math.min(charge_step, tool_charge)
|
||||
tool_charge = tool_charge - charge_step
|
||||
batt_charge = batt_charge + charge_step
|
||||
technic.set_RE_wear(srcstack, tool_charge, item_max_charge)
|
||||
src_meta.charge = tool_charge
|
||||
srcstack:set_metadata(minetest.serialize(src_meta))
|
||||
inv:set_stack("dst", 1, srcstack)
|
||||
technic_set_charge(src_stack, tool_charge)
|
||||
inv:set_stack("dst", 1, src_stack)
|
||||
return batt_charge, (tool_charge == 0)
|
||||
end
|
||||
|
||||
|
@ -63,24 +63,24 @@ local function clear_networks(pos)
|
||||
-- This is similar to check_node_subp
|
||||
technic.cables[minetest.hash_node_position(pos)] = network_id
|
||||
pos.visited = 1
|
||||
if technic.is_tier_cable(name, tier) then
|
||||
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
|
||||
meta:set_string(tier.."_network",minetest.pos_to_string(sw_pos))
|
||||
if technic.machines[tier][node.name] == technic.producer then
|
||||
table.insert(network.PR_nodes,pos)
|
||||
elseif technic.machines[tier][node.name] == technic.receiver then
|
||||
table.insert(network.RE_nodes,pos)
|
||||
elseif technic.machines[tier][node.name] == technic.producer_receiver then
|
||||
table.insert(network.PR_nodes,pos)
|
||||
table.insert(network.RE_nodes,pos)
|
||||
elseif technic.machines[tier][node.name] == "SPECIAL" and
|
||||
(pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) and
|
||||
from_below then
|
||||
table.insert(network.SP_nodes,pos)
|
||||
elseif technic.machines[tier][node.name] == technic.battery then
|
||||
table.insert(network.BA_nodes,pos)
|
||||
-- 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!
|
||||
end
|
||||
elseif dead_end and not placed then
|
||||
-- Dead end removed, remove it from the network
|
||||
|
@ -45,14 +45,12 @@ minetest.register_node("technic:switching_station",{
|
||||
meta:set_string("active", 1)
|
||||
meta:set_string("channel", "switching_station"..minetest.pos_to_string(pos))
|
||||
meta:set_string("formspec", "field[channel;Channel;${channel}]")
|
||||
local poshash = minetest.hash_node_position(pos)
|
||||
technic.redundant_warn.poshash = nil
|
||||
end,
|
||||
after_dig_node = function(pos)
|
||||
minetest.forceload_free_block(pos)
|
||||
pos.y = pos.y - 1
|
||||
minetest.forceload_free_block(pos)
|
||||
local poshash = minetest.hash_node_position(pos)
|
||||
technic.redundant_warn.poshash = nil
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
@ -100,8 +98,10 @@ local function flatten(map)
|
||||
end
|
||||
|
||||
-- Add a wire node to the LV/MV/HV network
|
||||
-- Returns: indicator whether the cable 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 = minetest.hash_node_position(pos)
|
||||
local node_id = hash_node_position(pos)
|
||||
technic.cables[node_id] = network_id
|
||||
if nodes[node_id] then
|
||||
return false
|
||||
@ -117,39 +117,45 @@ local function add_cable_node(nodes, pos, network_id, queue)
|
||||
end
|
||||
|
||||
-- Generic function to add found connected nodes to the right classification array
|
||||
local check_node_subp = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, pos, machines, tier, sw_pos, from_below, network_id, queue)
|
||||
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
|
||||
|
||||
if technic.is_tier_cable(name, tier) then
|
||||
add_cable_node(all_nodes, pos,network_id, queue)
|
||||
elseif machines[name] then
|
||||
--dprint(name.." is a "..machines[name])
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string(tier.."_network",minetest.pos_to_string(sw_pos))
|
||||
if machines[name] == technic.producer then
|
||||
add_network_node(PR_nodes, pos, network_id)
|
||||
elseif machines[name] == technic.receiver then
|
||||
add_network_node(RE_nodes, pos, network_id)
|
||||
elseif machines[name] == technic.producer_receiver then
|
||||
add_network_node(PR_nodes, pos, network_id)
|
||||
add_network_node(RE_nodes, pos, network_id)
|
||||
elseif machines[name] == "SPECIAL" and
|
||||
(pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) and
|
||||
from_below then
|
||||
-- Another switching station -> disable it
|
||||
add_network_node(SP_nodes, pos, network_id)
|
||||
meta:set_int("active", 0)
|
||||
elseif machines[name] == technic.battery then
|
||||
add_network_node(BA_nodes, pos, network_id)
|
||||
end
|
||||
|
||||
meta:set_int(tier.."_EU_timeout", 2) -- Touch node
|
||||
if technic.is_tier_cable(name, network.tier) then
|
||||
add_cable_node(network.all_nodes, pos, network_id, queue)
|
||||
return
|
||||
end
|
||||
|
||||
local eu_type = machines[name]
|
||||
if not eu_type then
|
||||
return
|
||||
end
|
||||
|
||||
--dprint(name.." is a "..machines[name])
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string(network.tier.."_network", minetest.pos_to_string(sw_pos))
|
||||
|
||||
if eu_type == technic.producer then
|
||||
add_network_node(network.PR_nodes, pos, network_id)
|
||||
elseif eu_type == technic.receiver then
|
||||
add_network_node(network.RE_nodes, pos, network_id)
|
||||
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)
|
||||
elseif eu_type == technic.battery then
|
||||
add_network_node(network.BA_nodes, pos, network_id)
|
||||
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)
|
||||
meta:set_int("active", 0)
|
||||
end
|
||||
|
||||
meta:set_int(network.tier.."_EU_timeout", 2) -- Touch node
|
||||
end
|
||||
|
||||
-- Traverse a network given a list of machines and a cable type name
|
||||
local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, pos, machines, tier, sw_pos, network_id, queue)
|
||||
local traverse_network = function(network, pos, machines, sw_pos, network_id, queue)
|
||||
local positions = {
|
||||
{x=pos.x+1, y=pos.y, z=pos.z},
|
||||
{x=pos.x-1, y=pos.y, z=pos.z},
|
||||
@ -158,7 +164,7 @@ local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_no
|
||||
{x=pos.x, y=pos.y, z=pos.z+1},
|
||||
{x=pos.x, y=pos.y, z=pos.z-1}}
|
||||
for i, cur_pos in pairs(positions) do
|
||||
check_node_subp(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, cur_pos, machines, tier, sw_pos, i == 3, network_id, queue)
|
||||
check_node_subp(network, cur_pos, machines, sw_pos, i == 3, network_id, queue)
|
||||
end
|
||||
end
|
||||
|
||||
@ -169,43 +175,51 @@ local touch_nodes = function(list, tier)
|
||||
end
|
||||
end
|
||||
|
||||
local get_network = function(sw_pos, pos1, tier)
|
||||
local network_id = minetest.hash_node_position(pos1)
|
||||
local get_network = function(sw_pos, cable_pos, tier)
|
||||
local network_id = minetest.hash_node_position(cable_pos)
|
||||
local cached = technic.networks[network_id]
|
||||
if cached and cached.tier == tier then
|
||||
-- Re-use cached system data
|
||||
touch_nodes(cached.PR_nodes, tier)
|
||||
touch_nodes(cached.BA_nodes, tier)
|
||||
touch_nodes(cached.RE_nodes, tier)
|
||||
for _, pos in ipairs(cached.SP_nodes) do
|
||||
-- Disable all other switching stations (again)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("active", 0)
|
||||
meta:set_string("active_pos", minetest.serialize(sw_pos))
|
||||
end
|
||||
return cached.PR_nodes, cached.BA_nodes, cached.RE_nodes
|
||||
end
|
||||
local PR_nodes = {}
|
||||
local BA_nodes = {}
|
||||
local RE_nodes = {}
|
||||
local SP_nodes = {}
|
||||
local all_nodes = {}
|
||||
|
||||
local machines = technic.machines[tier]
|
||||
local network = {
|
||||
tier = tier,
|
||||
PR_nodes = {},
|
||||
BA_nodes = {},
|
||||
RE_nodes = {},
|
||||
SP_nodes = {},
|
||||
all_nodes = {}
|
||||
}
|
||||
-- Traverse the network step by step starting from the node underneath the switching station
|
||||
local queue = {}
|
||||
add_cable_node(all_nodes, pos1, network_id, queue)
|
||||
add_cable_node(network.all_nodes, cable_pos, network_id, queue)
|
||||
while next(queue) do
|
||||
local to_visit = {}
|
||||
for _, pos in ipairs(queue) do
|
||||
traverse_network(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes,
|
||||
pos, technic.machines[tier], tier, sw_pos, network_id, to_visit)
|
||||
traverse_network(network, pos, machines, sw_pos, network_id, to_visit)
|
||||
end
|
||||
queue = to_visit
|
||||
end
|
||||
PR_nodes = flatten(PR_nodes)
|
||||
BA_nodes = flatten(BA_nodes)
|
||||
RE_nodes = flatten(RE_nodes)
|
||||
SP_nodes = flatten(SP_nodes)
|
||||
all_nodes = flatten(all_nodes)
|
||||
technic.networks[network_id] = {tier = tier, all_nodes = all_nodes, SP_nodes = SP_nodes,
|
||||
PR_nodes = PR_nodes, RE_nodes = RE_nodes, BA_nodes = BA_nodes}
|
||||
return PR_nodes, BA_nodes, RE_nodes
|
||||
|
||||
-- Convert { [hash] = pos, ... } to { pos, ... }
|
||||
network.PR_nodes = flatten(network.PR_nodes)
|
||||
network.BA_nodes = flatten(network.BA_nodes)
|
||||
network.RE_nodes = flatten(network.RE_nodes)
|
||||
network.SP_nodes = flatten(network.SP_nodes)
|
||||
network.all_nodes = flatten(network.all_nodes)
|
||||
technic.networks[network_id] = network
|
||||
|
||||
return network.PR_nodes, network.BA_nodes, network.RE_nodes
|
||||
end
|
||||
|
||||
-----------------------------------------------
|
||||
@ -215,19 +229,17 @@ end
|
||||
technic.powerctrl_state = true
|
||||
|
||||
minetest.register_chatcommand("powerctrl", {
|
||||
params = "state",
|
||||
params = "[on/off]",
|
||||
description = "Enables or disables technic's switching station ABM",
|
||||
privs = { basic_privs = true },
|
||||
func = function(name, state)
|
||||
if state == "on" then
|
||||
technic.powerctrl_state = true
|
||||
else
|
||||
technic.powerctrl_state = false
|
||||
end
|
||||
technic.powerctrl_state = (state:trim():lower() == "on")
|
||||
minetest.chat_send_player(name, "Technic switching station: " ..
|
||||
(technic.powerctrl_state and "on" or "off"))
|
||||
end
|
||||
})
|
||||
|
||||
-- Run all the nodes
|
||||
-- Run `technic_run` on all nodes in the power grid
|
||||
local function run_nodes(list, run_stage)
|
||||
for _, pos in ipairs(list) do
|
||||
technic.get_or_load_node(pos)
|
||||
@ -243,28 +255,23 @@ end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:switching_station"},
|
||||
label = "Switching Station", -- allows the mtt profiler to profile this abm individually
|
||||
label = "Switching Station", -- name for the Minetest mod profiler
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if not technic.powerctrl_state then return end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta1
|
||||
local pos1 = {}
|
||||
|
||||
local tier = ""
|
||||
local PR_nodes
|
||||
local BA_nodes
|
||||
local RE_nodes
|
||||
local PR_nodes, BA_nodes, RE_nodes
|
||||
local machine_name = S("Switching Station")
|
||||
|
||||
-- Which kind of network are we on:
|
||||
pos1 = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
local cable_pos = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
|
||||
--Disable if necessary
|
||||
if meta:get_int("active") ~= 1 then
|
||||
minetest.forceload_free_block(pos)
|
||||
minetest.forceload_free_block(pos1)
|
||||
minetest.forceload_free_block(cable_pos)
|
||||
meta:set_string("infotext",S("%s Already Present"):format(machine_name))
|
||||
|
||||
local poshash = minetest.hash_node_position(pos)
|
||||
@ -276,18 +283,18 @@ minetest.register_abm({
|
||||
return
|
||||
end
|
||||
|
||||
local name = minetest.get_node(pos1).name
|
||||
local name = minetest.get_node(cable_pos).name
|
||||
local tier = technic.get_cable_tier(name)
|
||||
if tier then
|
||||
-- Forceload switching station
|
||||
minetest.forceload_block(pos)
|
||||
minetest.forceload_block(pos1)
|
||||
PR_nodes, BA_nodes, RE_nodes = get_network(pos, pos1, tier)
|
||||
minetest.forceload_block(cable_pos)
|
||||
PR_nodes, BA_nodes, RE_nodes = get_network(pos, cable_pos, tier)
|
||||
else
|
||||
--dprint("Not connected to a network")
|
||||
meta:set_string("infotext", S("%s Has No Network"):format(machine_name))
|
||||
minetest.forceload_free_block(pos)
|
||||
minetest.forceload_free_block(pos1)
|
||||
minetest.forceload_free_block(cable_pos)
|
||||
return
|
||||
end
|
||||
|
||||
@ -340,20 +347,14 @@ minetest.register_abm({
|
||||
end
|
||||
--dprint("Total RE demand:"..RE_eu_demand)
|
||||
|
||||
-- Get all the power from the BA nodes
|
||||
local BA_eu_supply = 0
|
||||
-- Batteries
|
||||
local BA_eu_supply, BA_eu_demand = 0, 0
|
||||
for _, pos1 in pairs(BA_nodes) do
|
||||
meta1 = minetest.get_meta(pos1)
|
||||
BA_eu_supply = BA_eu_supply + meta1:get_int(eu_supply_str)
|
||||
end
|
||||
--dprint("Total BA supply:"..BA_eu_supply)
|
||||
|
||||
-- Get all the demand from the BA nodes
|
||||
local BA_eu_demand = 0
|
||||
for _, pos1 in pairs(BA_nodes) do
|
||||
meta1 = minetest.get_meta(pos1)
|
||||
BA_eu_demand = BA_eu_demand + meta1:get_int(eu_demand_str)
|
||||
end
|
||||
--dprint("Total BA supply:"..BA_eu_supply)
|
||||
--dprint("Total BA demand:"..BA_eu_demand)
|
||||
|
||||
meta:set_string("infotext", S("@1. Supply: @2 Demand: @3",
|
||||
@ -374,8 +375,8 @@ minetest.register_abm({
|
||||
end
|
||||
|
||||
-- Data that will be used by the power monitor
|
||||
meta:set_int("supply",PR_eu_supply)
|
||||
meta:set_int("demand",RE_eu_demand)
|
||||
meta:set_int("supply", PR_eu_supply)
|
||||
meta:set_int("demand", RE_eu_demand)
|
||||
|
||||
-- If the PR supply is enough for the RE demand supply them all
|
||||
if PR_eu_supply >= RE_eu_demand then
|
||||
|
@ -428,7 +428,7 @@ for _, state in pairs({"flowing", "source"}) do
|
||||
liquidtype = state,
|
||||
liquid_alternative_flowing = "technic:corium_flowing",
|
||||
liquid_alternative_source = "technic:corium_source",
|
||||
liquid_viscosity = LAVA_VISC,
|
||||
liquid_viscosity = 7, -- like lava
|
||||
liquid_renewable = false,
|
||||
damage_per_second = 6,
|
||||
post_effect_color = {a=192, r=80, g=160, b=80},
|
||||
|
@ -44,7 +44,10 @@ end
|
||||
|
||||
-- Wear down a tool depending on the remaining charge.
|
||||
function technic.set_RE_wear(itemstack, item_load, max_load)
|
||||
if (minetest.registered_items[itemstack:get_name()].wear_represents or "mechanical_wear") ~= "technic_RE_charge" then return itemstack end
|
||||
local def = minetest.registered_items[itemstack:get_name()]
|
||||
if (def.wear_represents or "mechanical_wear") ~= "technic_RE_charge" then
|
||||
return itemstack
|
||||
end
|
||||
local temp
|
||||
if item_load == 0 then
|
||||
temp = 0
|
||||
|
@ -36,7 +36,10 @@ function technic.register_can(d)
|
||||
local charge = get_can_level(itemstack)
|
||||
if charge == data.can_capacity then return end
|
||||
if minetest.is_protected(pointed_thing.under, user:get_player_name()) then
|
||||
minetest.log("action", user:get_player_name().." tried to take "..node.name.." at protected position "..minetest.pos_to_string(pointed_thing.under).." with a "..data.can_name)
|
||||
minetest.log("action", user:get_player_name()..
|
||||
" tried to take "..node.name..
|
||||
" at protected position "..minetest.pos_to_string(pointed_thing.under)..
|
||||
" with a "..data.can_name)
|
||||
return
|
||||
end
|
||||
minetest.remove_node(pointed_thing.under)
|
||||
@ -63,7 +66,10 @@ function technic.register_can(d)
|
||||
local charge = get_can_level(itemstack)
|
||||
if charge == 0 then return end
|
||||
if minetest.is_protected(pos, user:get_player_name()) then
|
||||
minetest.log("action", user:get_player_name().." tried to place "..data.liquid_source_name.." at protected position "..minetest.pos_to_string(pos).." with a "..data.can_name)
|
||||
minetest.log("action", user:get_player_name()..
|
||||
" tried to place "..data.liquid_source_name..
|
||||
" at protected position "..minetest.pos_to_string(pos)..
|
||||
" with a "..data.can_name)
|
||||
return
|
||||
end
|
||||
minetest.set_node(pos, {name=data.liquid_source_name})
|
||||
|
@ -46,20 +46,27 @@ local mining_drill_mode_text = {
|
||||
{S("3x3 nodes.")},
|
||||
}
|
||||
|
||||
local function drill_dig_it0 (pos,player)
|
||||
local function drill_dig_it0(pos, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
minetest.record_protection_violation(pos, player:get_player_name())
|
||||
return
|
||||
end
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == "air" or node.name == "ignore" then return end
|
||||
if node.name == "default:lava_source" then return end
|
||||
if node.name == "default:lava_flowing" then return end
|
||||
if node.name == "default:water_source" then minetest.remove_node(pos) return end
|
||||
if node.name == "default:water_flowing" then minetest.remove_node(pos) return end
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
if not def then return end
|
||||
def.on_dig(pos, node, player)
|
||||
local ndef = minetest.registered_nodes[node.name]
|
||||
if not ndef or ndef.drawtype == "airlike" then
|
||||
-- Covers "air", "ignore", unknown nodes and more.
|
||||
return
|
||||
end
|
||||
local groups = ndef and ndef.groups or {}
|
||||
|
||||
if groups.lava then
|
||||
return
|
||||
end
|
||||
if groups.water then
|
||||
minetest.remove_node(pos)
|
||||
return
|
||||
end
|
||||
ndef.on_dig(pos, node, player)
|
||||
end
|
||||
|
||||
local function drill_dig_it1 (player)
|
||||
@ -239,97 +246,61 @@ local function pos_is_pointable(pos)
|
||||
return nodedef and nodedef.pointable
|
||||
end
|
||||
|
||||
local function mining_drill_mk2_setmode(user,itemstack)
|
||||
local player_name=user:get_player_name()
|
||||
local item=itemstack:to_table()
|
||||
local mode = nil
|
||||
local meta=minetest.deserialize(item["metadata"])
|
||||
if meta==nil then
|
||||
meta={}
|
||||
mode=0
|
||||
local function mining_drill_mkX_setmode(user, itemstack, drill_type, max_modes)
|
||||
local player_name = user:get_player_name()
|
||||
local meta = minetest.deserialize(itemstack:get_metadata()) or {}
|
||||
|
||||
if not meta["mode"] then
|
||||
minetest.chat_send_player(player_name,
|
||||
S("Use while sneaking to change Mining Drill Mk%d modes."):format(drill_type))
|
||||
end
|
||||
if meta["mode"]==nil then
|
||||
minetest.chat_send_player(player_name, S("Use while sneaking to change Mining Drill Mk%d modes."):format(2))
|
||||
meta["mode"]=0
|
||||
mode=0
|
||||
end
|
||||
mode=(meta["mode"])
|
||||
mode=mode+1
|
||||
if mode>=5 then mode=1 end
|
||||
minetest.chat_send_player(player_name, S("Mining Drill Mk%d Mode %d"):format(2, mode)..": "..mining_drill_mode_text[mode][1])
|
||||
itemstack:set_name("technic:mining_drill_mk2_"..mode);
|
||||
meta["mode"]=mode
|
||||
local mode = (meta["mode"] or 0) + 1
|
||||
if mode > max_modes then mode = 1 end
|
||||
|
||||
minetest.chat_send_player(player_name,
|
||||
S("Mining Drill Mk%d Mode %d"):format(2, mode)..
|
||||
": "..mining_drill_mode_text[mode][1])
|
||||
itemstack:set_name(("technic:mining_drill_mk%d_%s"):format(drill_type, mode))
|
||||
meta["mode"] = mode
|
||||
itemstack:set_metadata(minetest.serialize(meta))
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local function mining_drill_mk3_setmode(user,itemstack)
|
||||
local player_name=user:get_player_name()
|
||||
local item=itemstack:to_table()
|
||||
local meta=minetest.deserialize(item["metadata"])
|
||||
if meta==nil then
|
||||
meta={}
|
||||
mode=0
|
||||
end
|
||||
if meta["mode"]==nil then
|
||||
minetest.chat_send_player(player_name, S("Use while sneaking to change Mining Drill Mk%d modes."):format(3))
|
||||
meta["mode"]=0
|
||||
mode=0
|
||||
end
|
||||
mode=(meta["mode"])
|
||||
mode=mode+1
|
||||
if mode>=6 then mode=1 end
|
||||
minetest.chat_send_player(player_name, S("Mining Drill Mk%d Mode %d"):format(3, mode)..": "..mining_drill_mode_text[mode][1])
|
||||
itemstack:set_name("technic:mining_drill_mk3_"..mode);
|
||||
meta["mode"]=mode
|
||||
itemstack:set_metadata(minetest.serialize(meta))
|
||||
return itemstack
|
||||
end
|
||||
|
||||
|
||||
local function mining_drill_mk2_handler(itemstack, user, pointed_thing)
|
||||
local function mining_drill_mkX_handler(itemstack, user, pointed_thing, drill_type, max_modes)
|
||||
local keys = user:get_player_control()
|
||||
local meta = minetest.deserialize(itemstack:get_metadata())
|
||||
if not meta or not meta.mode or keys.sneak then
|
||||
return mining_drill_mk2_setmode(user, itemstack)
|
||||
end
|
||||
if pointed_thing.type ~= "node" or not pos_is_pointable(pointed_thing.under) or not meta.charge then
|
||||
return
|
||||
end
|
||||
local charge_to_take = cost_to_use(2, meta.mode)
|
||||
if meta.charge >= charge_to_take then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
drill_dig_it(pos, user, meta.mode)
|
||||
if not technic.creative_mode then
|
||||
meta.charge = meta.charge - charge_to_take
|
||||
itemstack:set_metadata(minetest.serialize(meta))
|
||||
technic.set_RE_wear(itemstack, meta.charge, max_charge[2])
|
||||
local meta = minetest.deserialize(itemstack:get_metadata()) or {}
|
||||
|
||||
-- Mode switching (if possible)
|
||||
if max_modes > 1 then
|
||||
if not meta.mode or keys.sneak then
|
||||
return mining_drill_mkX_setmode(user, itemstack, drill_type, max_modes)
|
||||
end
|
||||
end
|
||||
if pointed_thing.type ~= "node" or not pos_is_pointable(pointed_thing.under) then
|
||||
return
|
||||
end
|
||||
if not meta.charge then
|
||||
return
|
||||
end
|
||||
|
||||
-- Check whether the tool has enough charge
|
||||
local charge_to_take = cost_to_use(drill_type, meta.mode or 1)
|
||||
if meta.charge < charge_to_take then
|
||||
return
|
||||
end
|
||||
|
||||
-- Do the actual shoorting action
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
drill_dig_it(pos, user, meta.mode or 1)
|
||||
if not technic.creative_mode then
|
||||
meta.charge = meta.charge - charge_to_take
|
||||
itemstack:set_metadata(minetest.serialize(meta))
|
||||
technic.set_RE_wear(itemstack, meta.charge, max_charge[drill_type])
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local function mining_drill_mk3_handler(itemstack, user, pointed_thing)
|
||||
local keys = user:get_player_control()
|
||||
local meta = minetest.deserialize(itemstack:get_metadata())
|
||||
if not meta or not meta.mode or keys.sneak then
|
||||
return mining_drill_mk3_setmode(user, itemstack)
|
||||
end
|
||||
if pointed_thing.type ~= "node" or not pos_is_pointable(pointed_thing.under) or not meta.charge then
|
||||
return
|
||||
end
|
||||
local charge_to_take = cost_to_use(3, meta.mode)
|
||||
if meta.charge >= charge_to_take then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
drill_dig_it(pos, user, meta.mode)
|
||||
if not technic.creative_mode then
|
||||
meta.charge = meta.charge - charge_to_take
|
||||
itemstack:set_metadata(minetest.serialize(meta))
|
||||
technic.set_RE_wear(itemstack, meta.charge, max_charge[3])
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
-- Simple mining drill registration
|
||||
|
||||
technic.register_power_tool("technic:mining_drill", max_charge[1])
|
||||
|
||||
@ -340,34 +311,20 @@ minetest.register_tool("technic:mining_drill", {
|
||||
wear_represents = "technic_RE_charge",
|
||||
on_refill = technic.refill_RE_charge,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if pointed_thing.type ~= "node" or not pos_is_pointable(pointed_thing.under) then
|
||||
return itemstack
|
||||
end
|
||||
local meta = minetest.deserialize(itemstack:get_metadata())
|
||||
if not meta or not meta.charge then
|
||||
return
|
||||
end
|
||||
local charge_to_take = cost_to_use(1, 1)
|
||||
if meta.charge >= charge_to_take then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
drill_dig_it(pos, user, 1)
|
||||
if not technic.creative_mode then
|
||||
meta.charge = meta.charge - charge_to_take
|
||||
itemstack:set_metadata(minetest.serialize(meta))
|
||||
technic.set_RE_wear(itemstack, meta.charge, max_charge[1])
|
||||
end
|
||||
end
|
||||
mining_drill_mkX_handler(itemstack, user, pointed_thing, 1, 1)
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
-- Mk2 registration
|
||||
|
||||
minetest.register_tool("technic:mining_drill_mk2", {
|
||||
description = S("Mining Drill Mk%d"):format(2),
|
||||
inventory_image = "technic_mining_drill_mk2.png",
|
||||
wear_represents = "technic_RE_charge",
|
||||
on_refill = technic.refill_RE_charge,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
mining_drill_mk2_handler(itemstack, user, pointed_thing)
|
||||
mining_drill_mkX_handler(itemstack, user, pointed_thing, 2, 4)
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
@ -384,20 +341,22 @@ for i = 1, 4 do
|
||||
on_refill = technic.refill_RE_charge,
|
||||
groups = {not_in_creative_inventory=1},
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
mining_drill_mk2_handler(itemstack, user, pointed_thing)
|
||||
mining_drill_mkX_handler(itemstack, user, pointed_thing, 2, 4)
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
-- Mk3 registration
|
||||
|
||||
minetest.register_tool("technic:mining_drill_mk3", {
|
||||
description = S("Mining Drill Mk%d"):format(3),
|
||||
inventory_image = "technic_mining_drill_mk3.png",
|
||||
wear_represents = "technic_RE_charge",
|
||||
on_refill = technic.refill_RE_charge,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
mining_drill_mk3_handler(itemstack,user,pointed_thing)
|
||||
return itemstack
|
||||
mining_drill_mkX_handler(itemstack, user, pointed_thing, 3, 5)
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
@ -413,8 +372,8 @@ for i=1,5,1 do
|
||||
on_refill = technic.refill_RE_charge,
|
||||
groups = {not_in_creative_inventory=1},
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
mining_drill_mk3_handler(itemstack,user,pointed_thing)
|
||||
return itemstack
|
||||
mining_drill_mkX_handler(itemstack, user, pointed_thing, 3, 5)
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
@ -33,6 +33,7 @@ minetest.register_tool("technic:prospector", {
|
||||
toolstack:set_metadata(minetest.serialize(toolmeta))
|
||||
technic.set_RE_wear(toolstack, toolmeta.charge, technic.power_tools[toolstack:get_name()])
|
||||
end
|
||||
-- What in the heaven's name is this evil sorcery ?
|
||||
local start_pos = pointed_thing.under
|
||||
local forward = minetest.facedir_to_dir(minetest.dir_to_facedir(user:get_look_dir(), true))
|
||||
local right = forward.x ~= 0 and { x=0, y=1, z=0 } or (forward.y ~= 0 and { x=0, y=0, z=1 } or { x=1, y=0, z=0 })
|
||||
@ -42,13 +43,36 @@ minetest.register_tool("technic:prospector", {
|
||||
for f = 0, toolmeta.look_depth-1 do
|
||||
for r = 0, look_diameter-1 do
|
||||
for u = 0, look_diameter-1 do
|
||||
if minetest.get_node(vector.add(vector.add(vector.add(base_pos, vector.multiply(forward, f)), vector.multiply(right, r)), vector.multiply(up, u))).name == toolmeta.target then found = true end
|
||||
if minetest.get_node(
|
||||
vector.add(
|
||||
vector.add(
|
||||
vector.add(base_pos,
|
||||
vector.multiply(forward, f)),
|
||||
vector.multiply(right, r)),
|
||||
vector.multiply(up, u))
|
||||
).name == toolmeta.target then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if found then break end
|
||||
end
|
||||
if found then break end
|
||||
end
|
||||
if math.random() < 0.02 then found = not found end
|
||||
minetest.chat_send_player(user:get_player_name(), minetest.registered_nodes[toolmeta.target].description.." is "..(found and "present" or "absent").." in "..look_diameter.."x"..look_diameter.."x"..toolmeta.look_depth.." region")
|
||||
minetest.sound_play("technic_prospector_"..(found and "hit" or "miss"), { pos = vector.add(user:get_pos(), { x = 0, y = 1, z = 0 }), gain = 1.0, max_hear_distance = 10 })
|
||||
if math.random() < 0.02 then
|
||||
found = not found
|
||||
end
|
||||
|
||||
local ndef = minetest.registered_nodes[toolmeta.target]
|
||||
minetest.chat_send_player(user:get_player_name(),
|
||||
ndef.description.." is "..(found and "present" or "absent")..
|
||||
" in "..look_diameter.."x"..look_diameter.."x"..toolmeta.look_depth.." region")
|
||||
|
||||
minetest.sound_play("technic_prospector_"..(found and "hit" or "miss"), {
|
||||
pos = vector.add(user:get_pos(), { x = 0, y = 1, z = 0 }),
|
||||
gain = 1.0,
|
||||
max_hear_distance = 10
|
||||
})
|
||||
return toolstack
|
||||
end,
|
||||
on_place = function(toolstack, user, pointed_thing)
|
||||
|
@ -1,7 +0,0 @@
|
||||
default
|
||||
basic_materials
|
||||
moreblocks?
|
||||
moreores?
|
||||
pipeworks?
|
||||
intllib?
|
||||
tubelib?
|
@ -1,7 +1,7 @@
|
||||
local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
|
||||
|
||||
local pipeworks = rawget(_G, "pipeworks")
|
||||
local fs_helpers = rawget(_G, "fs_helpers")
|
||||
local fs_helpers
|
||||
local tubelib_exists = minetest.global_exists("tubelib")
|
||||
|
||||
local allow_label = ""
|
||||
@ -97,7 +97,8 @@ local function set_formspec(pos, data, page)
|
||||
|
||||
if data.autosort then
|
||||
local status = meta:get_int("autosort")
|
||||
formspec = formspec.."button["..(data.hileft+2)..","..(data.height+1.1)..";3,0.8;autosort_to_"..(1-status)..";"..S("Auto-sort is %s"):format(status == 1 and S("On") or S("Off")).."]"
|
||||
formspec = formspec.."button["..(data.hileft+2)..","..(data.height+1.1)..";3,0.8;autosort_to_"..(1-status)..";"..
|
||||
S("Auto-sort is %s"):format(status == 1 and S("On") or S("Off")).."]"
|
||||
end
|
||||
if data.infotext then
|
||||
local formspec_infotext = minetest.formspec_escape(meta:get_string("infotext"))
|
||||
@ -221,7 +222,6 @@ function technic.chests:definition(name, data)
|
||||
data.lotop = data.height + 2
|
||||
data.ovheight = data.lotop + 4
|
||||
|
||||
local locked_after_place = nil
|
||||
local front = {"technic_"..lname.."_chest_front.png"}
|
||||
data.base_formspec = "size["..data.ovwidth..","..data.ovheight.."]"..
|
||||
"label[0,0;"..S("%s Chest"):format(name).."]"..
|
||||
@ -239,6 +239,7 @@ function technic.chests:definition(name, data)
|
||||
data.base_formspec = data.base_formspec..get_color_buttons(data.coleft, data.lotop)
|
||||
end
|
||||
|
||||
local locked_after_place
|
||||
if data.locked then
|
||||
locked_after_place = function(pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
@ -163,12 +163,12 @@ local function form_handler(pos, formname, fields, sender)
|
||||
local inv = meta:get_inventory()
|
||||
local inputstack = inv:get_stack("src", 1)
|
||||
local inputname = inputstack:get_name()
|
||||
local multiplier = 0
|
||||
local size = meta:get_int("size")
|
||||
if size < 1 then size = 1 end
|
||||
|
||||
for k, _ in pairs(fields) do
|
||||
-- Set a multipier for the half/full size capable blocks
|
||||
local multiplier
|
||||
if twosize_products[k] ~= nil then
|
||||
multiplier = size * twosize_products[k]
|
||||
else
|
||||
|
@ -2,6 +2,7 @@
|
||||
-- Again code is adapted from the NonCubic Blocks MOD v1.4 by yves_de_beck
|
||||
|
||||
local S = technic_cnc.getter
|
||||
local ALPHA_CLIP = minetest.features.use_texture_alpha_string_modes and "clip" or true
|
||||
|
||||
-- REGISTER NONCUBIC FORMS, CREATE MODELS AND RECIPES:
|
||||
------------------------------------------------------
|
||||
@ -298,6 +299,7 @@ function technic_cnc.register_program(recipeitem, suffix, model, groups, images,
|
||||
tiles = images,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
use_texture_alpha = ALPHA_CLIP,
|
||||
walkable = true,
|
||||
groups = groups,
|
||||
selection_box = sbox,
|
||||
@ -325,11 +327,10 @@ function technic_cnc.register_all(recipeitem, groups, images, description)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- REGISTER NEW TECHNIC_CNC_API's PART 2: technic_cnc..register_element_end(subname, recipeitem, groups, images, desc_element_xyz)
|
||||
-----------------------------------------------------------------------------------------------------------------------
|
||||
function technic_cnc.register_slope_edge_etc(recipeitem, groups, images, desc_slope, desc_slope_lying, desc_slope_upsdown, desc_slope_edge, desc_slope_inner_edge, desc_slope_upsdwn_edge, desc_slope_upsdwn_inner_edge, desc_pyramid, desc_spike, desc_onecurvededge, desc_twocurvededge, desc_cylinder, desc_cylinder_horizontal, desc_spheroid, desc_element_straight, desc_element_edge, desc_element_t, desc_element_cross, desc_element_end)
|
||||
|
||||
-- TODO: Remove this evil sorcery
|
||||
technic_cnc.register_slope(recipeitem, groups, images, desc_slope)
|
||||
technic_cnc.register_slope_lying(recipeitem, groups, images, desc_slope_lying)
|
||||
technic_cnc.register_slope_upsdown(recipeitem, groups, images, desc_slope_upsdown)
|
||||
@ -354,10 +355,12 @@ end
|
||||
-- REGISTER STICKS: noncubic.register_xyz(recipeitem, groups, images, desc_element_xyz)
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
function technic_cnc.register_stick_etc(recipeitem, groups, images, desc_stick)
|
||||
-- TODO: Remove this evil sorcery
|
||||
technic_cnc.register_stick(recipeitem, groups, images, desc_stick)
|
||||
end
|
||||
|
||||
function technic_cnc.register_elements(recipeitem, groups, images, desc_element_straight_double, desc_element_edge_double, desc_element_t_double, desc_element_cross_double, desc_element_end_double)
|
||||
-- TODO: Remove this evil sorcery
|
||||
technic_cnc.register_element_straight_double(recipeitem, groups, images, desc_element_straight_double)
|
||||
technic_cnc.register_element_edge_double(recipeitem, groups, images, desc_element_edge_double)
|
||||
technic_cnc.register_element_t_double(recipeitem, groups, images, desc_element_t_double)
|
||||
|
@ -1,3 +0,0 @@
|
||||
default
|
||||
basic_materials
|
||||
technic?
|
@ -10,7 +10,17 @@ technic_cnc.use_technic = technic_cnc.technic_modpath
|
||||
if rawget(_G, "intllib") then
|
||||
technic_cnc.getter = intllib.Getter()
|
||||
else
|
||||
technic_cnc.getter = function(s,a,...)if a==nil then return s end a={a,...}return s:gsub("(@?)@(%(?)(%d+)(%)?)",function(e,o,n,c)if e==""then return a[tonumber(n)]..(o==""and c or"")else return"@"..o..n..c end end) end
|
||||
-- Intllib copypasta: TODO replace with the client-side translation API
|
||||
technic_cnc.getter = function(s,a,...)
|
||||
if a==nil then return s end
|
||||
a={a,...}
|
||||
return s:gsub("(@?)@(%(?)(%d+)(%)?)", function(e,o,n,c)
|
||||
if e==""then
|
||||
return a[tonumber(n)]..(o==""and c or"")
|
||||
end
|
||||
return "@"..o..n..c
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
dofile(modpath.."/cnc.lua")
|
||||
|
@ -1,9 +0,0 @@
|
||||
default
|
||||
basic_materials
|
||||
intllib?
|
||||
mg?
|
||||
doors?
|
||||
farming?
|
||||
glooptest?
|
||||
mesecons_doors?
|
||||
vessels?
|
@ -1,6 +0,0 @@
|
||||
default
|
||||
technic?
|
||||
technic_chests?
|
||||
technic_worldgen?
|
||||
intllib?
|
||||
|
@ -32,34 +32,37 @@ local function get_pickup_name(name)
|
||||
end
|
||||
|
||||
local function restore(pos, placer, itemstack)
|
||||
local name = itemstack:get_name()
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local data = itemstack:get_meta():get_string("data")
|
||||
data = (data ~= "" and data) or itemstack:get_metadata()
|
||||
data = minetest.deserialize(data)
|
||||
|
||||
if not data then
|
||||
minetest.remove_node(pos)
|
||||
minetest.log("error", placer:get_player_name().." wanted to place "..
|
||||
name.." at "..minetest.pos_to_string(pos)..
|
||||
itemstack:get_name().." at "..minetest.pos_to_string(pos)..
|
||||
", but it had no data.")
|
||||
minetest.log("verbose", "itemstack: "..itemstack:to_string())
|
||||
return true
|
||||
end
|
||||
|
||||
local node = minetest.get_node(pos)
|
||||
minetest.set_node(pos, {name = data.name, param2 = node.param2})
|
||||
for name, value in pairs(data.metas) do
|
||||
local meta_type = get_meta_type(data.name, name)
|
||||
|
||||
-- Apply stored metadata to the current node
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
for key, value in pairs(data.metas) do
|
||||
local meta_type = get_meta_type(data.name, key)
|
||||
if meta_type == wrench.META_TYPE_INT then
|
||||
meta:set_int(name, value)
|
||||
meta:set_int(key, value)
|
||||
elseif meta_type == wrench.META_TYPE_FLOAT then
|
||||
meta:set_float(name, value)
|
||||
meta:set_float(key, value)
|
||||
elseif meta_type == wrench.META_TYPE_STRING then
|
||||
meta:set_string(name, value)
|
||||
meta:set_string(key, value)
|
||||
end
|
||||
end
|
||||
local lists = data.lists
|
||||
for listname, list in pairs(lists) do
|
||||
|
||||
for listname, list in pairs(data.lists) do
|
||||
inv:set_list(listname, list)
|
||||
end
|
||||
itemstack:take_item()
|
||||
@ -108,15 +111,15 @@ minetest.register_tool("wrench:wrench", {
|
||||
minetest.record_protection_violation(pos, player_name)
|
||||
return
|
||||
end
|
||||
local name = minetest.get_node(pos).name
|
||||
local def = wrench.registered_nodes[name]
|
||||
local node_name = minetest.get_node(pos).name
|
||||
local def = wrench.registered_nodes[node_name]
|
||||
if not def then
|
||||
return
|
||||
end
|
||||
|
||||
local stack = ItemStack(get_pickup_name(name))
|
||||
local stack_pickup = ItemStack(get_pickup_name(node_name))
|
||||
local player_inv = placer:get_inventory()
|
||||
if not player_inv:room_for_item("main", stack) then
|
||||
if not player_inv:room_for_item("main", stack_pickup) then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
@ -131,10 +134,12 @@ minetest.register_tool("wrench:wrench", {
|
||||
end
|
||||
end
|
||||
|
||||
-- Do the actual pickup:
|
||||
local metadata = {}
|
||||
metadata.name = name
|
||||
metadata.name = node_name
|
||||
metadata.version = LATEST_SERIALIZATION_VERSION
|
||||
|
||||
-- Serialize inventory lists + items
|
||||
local inv = meta:get_inventory()
|
||||
local lists = {}
|
||||
for _, listname in pairs(def.lists or {}) do
|
||||
@ -146,22 +151,23 @@ minetest.register_tool("wrench:wrench", {
|
||||
end
|
||||
metadata.lists = lists
|
||||
|
||||
local item_meta = stack:get_meta()
|
||||
-- Serialize node metadata fields
|
||||
local item_meta = stack_pickup:get_meta()
|
||||
metadata.metas = {}
|
||||
for name, meta_type in pairs(def.metas or {}) do
|
||||
for key, meta_type in pairs(def.metas or {}) do
|
||||
if meta_type == wrench.META_TYPE_INT then
|
||||
metadata.metas[name] = meta:get_int(name)
|
||||
metadata.metas[key] = meta:get_int(key)
|
||||
elseif meta_type == wrench.META_TYPE_FLOAT then
|
||||
metadata.metas[name] = meta:get_float(name)
|
||||
metadata.metas[key] = meta:get_float(key)
|
||||
elseif meta_type == wrench.META_TYPE_STRING then
|
||||
metadata.metas[name] = meta:get_string(name)
|
||||
metadata.metas[key] = meta:get_string(key)
|
||||
end
|
||||
end
|
||||
|
||||
item_meta:set_string("data", minetest.serialize(metadata))
|
||||
minetest.remove_node(pos)
|
||||
itemstack:add_wear(65535 / 20)
|
||||
player_inv:add_item("main", stack)
|
||||
player_inv:add_item("main", stack_pickup)
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
Reference in New Issue
Block a user