2 Commits

Author SHA1 Message Date
d69064c14e Annule le commit précédent car correction apporté dans moretrees 2020-06-13 14:44:14 +02:00
12b65e857b Corrige spawn des rubber trees
Le problème était que si moretrees était détecté, alors technic laissait
la main à moretrees pour la génération des rubber tree. Mais cette
génération ne fonctionne pas avec les mapgen v7, valleys, carpathian.
Résolue en forçant la génération des rubber tree par technic.
2020-05-09 19:42:28 +02:00
202 changed files with 1792 additions and 2353 deletions

View File

@ -1,20 +0,0 @@
---
name: Bug report
about: Report a problem within technic
title: ''
labels: Bug
assignees: ''
---
Technic has no main developer and largely depends on
user-provided Pull Requests. It will take a while until
even important issues are noticed.
Please consider proposing a PR directly.
_______________________________________________
**Bug description**
**Steps to reproduce this issue**

View File

@ -1,11 +0,0 @@
on: [push, pull_request]
name: Check & Release
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: lint
uses: Roang-zero1/factorio-mod-luacheck@master
with:
luacheckrc_url: ""

View File

@ -1,40 +0,0 @@
unused_args = false
allow_defined_top = true
max_line_length = 150
-- Allow shadowed variables (callbacks in callbacks)
redefined = false
globals = {
"technic", "minetest",
"srcstack",
}
read_globals = {
string = {fields = {"split", "trim"}},
table = {fields = {"copy", "getn"}},
"intllib", "VoxelArea",
"default", "stairsplus",
"PseudoRandom", "ItemStack",
"mg", "tubelib", "vector",
"moretrees", "bucket",
"unified_inventory", "digilines",
"pipeworks", "screwdriver",
"VoxelManip", "unifieddyes",
"Settings", "mesecon",
"digiline_remote",
"protector", "isprotect",
"homedecor_expect_infinite_stacks",
"craftguide", "i3"
}
-- Loop warning
files["technic/machines/other/frames.lua"].ignore = { "" }
-- Long lines
files["technic_cnc/cnc_api.lua"].ignore = { "" }

View File

@ -1,16 +0,0 @@
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

View File

@ -1,55 +1,23 @@
# Technic Technic
=======
[![Build status](https://github.com/minetest-mods/technic/workflows/Check%20&%20Release/badge.svg)](https://github.com/minetest-mods/technic/actions)
[![License](https://img.shields.io/badge/license-LGPLv2.0%2B-purple.svg)](https://www.gnu.org/licenses/old-licenses/lgpl-2.0.en.html)
This Minetest modpack adds machinery and automation procedure content to your
world. A few notable features:
* Electric circuits
* Automated material processing (ores, wood, ...)
* Extended chest functionalities
## Dependencies
* Minetest 5.0.0 or newer
* [Minetest Game](https://github.com/minetest/minetest_game/)
* [mesecons](https://github.com/minetest-mods/mesecons) -> signalling events
* [pipeworks](https://github.com/mt-mods/pipeworks) -> automation of item transport
* [moreores](https://github.com/minetest-mods/moreores/) -> additional ores
* [basic_materials](https://github.com/mt-mods/basic_materials) -> basic craft items
* Supports [moretrees](https://github.com/mt-mods/moretrees) -> rubber trees
* Consult `depends.txt` or `mod.conf` of each mod for further dependency information.
## FAQ
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.
2. My wires do not connect to the machines.
* Each machine type requires its own cable type. If you do not have a
matching circuit, consider using a "Supply Converter" for simplicity.
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](LICENSE.txt). See also the individual mod folders for their
secondary/alternate licenses, if any.
### Credits
Contributors in alphabetical order:
Credits for contributing to the project (in alphabetical order):
* kpoppel * kpoppel
* Nekogloop * Nekogloop
* Nore/Ekdohibs * Nore/Ekdohibs
* ShadowNinja * ShadowNinja
* VanessaE * VanessaE
* And many others... * And many others...
FAQ
---
1. My technic circuit doesn't work. No power is distrubuted.
* A: Make sure you have a switching station connected.
License
-------
Unless otherwise stated, all components of this modpack are licensed under the
LGPL, V2 or later. See also the individual mod folders for their
secondary/alternate licenses, if any.

4
concrete/depends.txt Normal file
View File

@ -0,0 +1,4 @@
default
basic_materials
intllib?
moreblocks?

View File

@ -16,6 +16,13 @@ for i = 32, 63 do
"technic:concrete_post_with_platform") "technic:concrete_post_with_platform")
end 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({ minetest.register_craft({
output = 'technic:concrete_post_platform 6', output = 'technic:concrete_post_platform 6',
recipe = { recipe = {

View File

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

9
extranodes/depends.txt Normal file
View File

@ -0,0 +1,9 @@
default
technic_worldgen
basic_materials
concrete
unifieddyes?
intllib?
moreblocks?
steel?
streetsmod?

View File

@ -27,12 +27,6 @@ if minetest.get_modpath("moreblocks") then
tiles={"technic_granite.png"}, tiles={"technic_granite.png"},
}) })
stairsplus:register_all("technic", "granite_bricks", "technic:granite_bricks", {
description=S("Granite Bricks"),
groups={cracky=1, not_in_creative_inventory=1},
tiles={"technic_granite_bricks.png"},
})
stairsplus:register_all("technic", "concrete", "technic:concrete", { stairsplus:register_all("technic", "concrete", "technic:concrete", {
description=S("Concrete"), description=S("Concrete"),
groups={cracky=3, not_in_creative_inventory=1}, groups={cracky=3, not_in_creative_inventory=1},
@ -63,47 +57,36 @@ if minetest.get_modpath("moreblocks") then
tiles={"technic_stainless_steel_block.png"}, tiles={"technic_stainless_steel_block.png"},
}) })
function register_technic_stairs_alias(origmod, origname, newmod, newname) function register_technic_stairs_alias(modname, origname, newmod, newname)
local func = minetest.register_alias minetest.register_alias(modname .. ":slab_" .. origname, newmod..":slab_" .. newname)
local function remap(kind, suffix) minetest.register_alias(modname .. ":slab_" .. origname .. "_inverted", newmod..":slab_" .. newname .. "_inverted")
-- Old: stairsplus:slab_concrete_wall minetest.register_alias(modname .. ":slab_" .. origname .. "_wall", newmod..":slab_" .. newname .. "_wall")
-- New: technic:slab_concrete_wall minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter", newmod..":slab_" .. newname .. "_quarter")
func(("%s:%s_%s%s"):format(origmod, kind, origname, suffix), minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter_inverted", newmod..":slab_" .. newname .. "_quarter_inverted")
("%s:%s_%s%s"):format(newmod, kind, newname, suffix)) minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter_wall", newmod..":slab_" .. newname .. "_quarter_wall")
end 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")
-- Slabs minetest.register_alias(modname .. ":slab_" .. origname .. "_three_quarter_wall", newmod..":slab_" .. newname .. "_three_quarter_wall")
remap("slab", "") minetest.register_alias(modname .. ":stair_" .. origname, newmod..":stair_" .. newname)
remap("slab", "_inverted") minetest.register_alias(modname .. ":stair_" .. origname .. "_inverted", newmod..":stair_" .. newname .. "_inverted")
remap("slab", "_wall") minetest.register_alias(modname .. ":stair_" .. origname .. "_wall", newmod..":stair_" .. newname .. "_wall")
remap("slab", "_quarter") minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half", newmod..":stair_" .. newname .. "_wall_half")
remap("slab", "_quarter_inverted") minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half_inverted", newmod..":stair_" .. newname .. "_wall_half_inverted")
remap("slab", "_quarter_wall") minetest.register_alias(modname .. ":stair_" .. origname .. "_half", newmod..":stair_" .. newname .. "_half")
remap("slab", "_three_quarter") minetest.register_alias(modname .. ":stair_" .. origname .. "_half_inverted", newmod..":stair_" .. newname .. "_half_inverted")
remap("slab", "_three_quarter_inverted") minetest.register_alias(modname .. ":stair_" .. origname .. "_right_half", newmod..":stair_" .. newname .. "_right_half")
remap("slab", "_three_quarter_wall") 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")
-- Stairs minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half_inverted", newmod..":stair_" .. newname .. "_wall_half_inverted")
remap("stair", "") minetest.register_alias(modname .. ":stair_" .. origname .. "_inner", newmod..":stair_" .. newname .. "_inner")
remap("stair", "_inverted") minetest.register_alias(modname .. ":stair_" .. origname .. "_inner_inverted", newmod..":stair_" .. newname .. "_inner_inverted")
remap("stair", "_wall") minetest.register_alias(modname .. ":stair_" .. origname .. "_outer", newmod..":stair_" .. newname .. "_outer")
remap("stair", "_wall_half") minetest.register_alias(modname .. ":stair_" .. origname .. "_outer_inverted", newmod..":stair_" .. newname .. "_outer_inverted")
remap("stair", "_wall_half_inverted") minetest.register_alias(modname .. ":panel_" .. origname .. "_bottom", newmod..":panel_" .. newname .. "_bottom")
remap("stair", "_half") minetest.register_alias(modname .. ":panel_" .. origname .. "_top", newmod..":panel_" .. newname .. "_top")
remap("stair", "_half_inverted") minetest.register_alias(modname .. ":panel_" .. origname .. "_vertical", newmod..":panel_" .. newname .. "_vertical")
remap("stair", "_right_half") minetest.register_alias(modname .. ":micro_" .. origname .. "_bottom", newmod..":micro_" .. newname .. "_bottom")
remap("stair", "_right_half_inverted") minetest.register_alias(modname .. ":micro_" .. origname .. "_top", newmod..":micro_" .. newname .. "_top")
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 end
register_technic_stairs_alias("stairsplus", "concrete", "technic", "concrete") register_technic_stairs_alias("stairsplus", "concrete", "technic", "concrete")

View File

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

670
manual.md
View File

@ -1,241 +1,354 @@
# Technic User Manual Minetest technic modpack user manual
====================================
The technic modpack extends Minetest Game (shipped with Minetest by default) The technic modpack extends the Minetest game with many new elements,
with many new elements, mainly constructable machines and tools. This manual mainly constructable machines and tools. It is a large modpack, and
describes how to use the modpack, mainly from a player's perspective. tends to dominate gameplay when it is used. This manual describes how
to use the technic modpack, mainly from a player's perspective.
Documentation of the mod dependencies can be found here: The technic modpack depends on some other modpacks:
* the basic Minetest game
* mesecons, which supports the construction of logic systems based on
signalling elements
* pipeworks, which supports the automation of item transport
* moreores, which provides some additional ore types
* basic_materials, which provides some basic craft items
This manual doesn't explain how to use these other modpacks, which have
their own manuals:
* [Minetest Game Documentation](https://wiki.minetest.net/Main_Page) * [Minetest Game Documentation](https://wiki.minetest.net/Main_Page)
* [Mesecons Documentation](http://mesecons.net/items.html) * [Mesecons Documentation](http://mesecons.net/items.html)
* [Pipeworks Documentation](https://github.com/mt-mods/pipeworks/wiki/) * [Pipeworks Documentation](https://gitlab.com/VanessaE/pipeworks/-/wikis/home)
* [Moreores Forum Post](https://forum.minetest.net/viewtopic.php?t=549) * [Moreores Forum Post](https://forum.minetest.net/viewtopic.php?t=549)
* [Basic materials Repository](https://gitlab.com/VanessaE/basic_materials) * [Basic materials Repository](https://gitlab.com/VanessaE/basic_materials)
## 1.0 Recipes Recipes for constructable items in technic are generally not guessable,
and are also not specifically documented here. You should use a
craft guide mod to look up the recipes in-game. For the best possible
guidance, use the unified\_inventory mod, with which technic registers
its specialised recipe types.
Recipes for items registered by technic are not specifically documented here. substances
Please consult a craft guide mod to look up the recipes in-game. ----------
**Recommended mod:** [Unified Inventory](https://github.com/minetest-mods/unified_inventory) ### ore ###
## 2.0 Substances The technic mod makes extensive use of not just the default ores but also
some that are added by mods. You will need to mine for all the ore types
in the course of the game. Each ore type is found at a specific range of
elevations, and while the ranges mostly overlap, some have non-overlapping
ranges, so you will ultimately need to mine at more than one elevation
to find all the ores. Also, because one of the best elevations to mine
at is very deep, you will be unable to mine there early in the game.
### 2.1 Ores Elevation is measured in meters, relative to a reference plane that
is not quite sea level. (The standard sea level is at an elevation
of about +1.4.) Positive elevations are above the reference plane and
negative elevations below. Because elevations are always described this
way round, greater numbers when higher, we avoid the word "depth".
Technic registers a few ores which are needed to craft machines or items. The ores that matter in technic are coal, iron, copper, tin, zinc,
Each ore type is found at a specific range of elevations so you will chromium, uranium, silver, gold, mithril, mese, and diamond.
ultimately need to mine at more than one elevation to find all the ores.
Elevation (Y axis) is measured in meters. The reference is usually at sea Coal is part of the basic Minetest game. It is found from elevation
level. Ores can generally be found more commonly by going downwards to -1000m. +64 downwards, so is available right on the surface at the start of
the game, but it is far less abundant above elevation 0 than below.
It is initially used as a fuel, driving important machines in the early
part of the game. It becomes less important as a fuel once most of your
machines are electrically powered, but burning fuel remains a way to
generate electrical power. Coal is also used, usually in dust form, as
an ingredient in alloying recipes, wherever elemental carbon is required.
Note ¹: *These ores are provided by Minetest Game. See [Ores](https://wiki.minetest.net/Ores#Ores_overview) for a rough overview* Iron is part of the basic Minetest game. It is found from elevation
+2 downwards, and its abundance increases in stages as one descends,
reaching its maximum from elevation -64 downwards. It is a common metal,
used frequently as a structural component. In technic, unlike the basic
game, iron is used in multiple forms, mainly alloys based on iron and
including carbon (coal).
Note ²: *These ores are provided by moreores. TODO: Add reference link* Copper is part of the basic Minetest game (having migrated there from
moreores). It is found from elevation -16 downwards, but is more abundant
#### Chromium from elevation -64 downwards. It is a common metal, used either on its
Use: stainless steel own for its electrical conductivity, or as the base component of alloys.
Generated below: -100m, more commonly below -200m
#### Coal ¹
Use: Fuel, alloy as carbon
Burning coal is a way to generate electrical power. Coal is also used,
usually in dust form, as an ingredient in alloying recipes, wherever
elemental carbon is required.
#### Copper ¹
Copper is a common metal, used either on its own for its electrical
conductivity, or as the base component of alloys.
Although common, it is very heavily used, and most of the time it will Although common, it is very heavily used, and most of the time it will
be the material that most limits your activity. be the material that most limits your activity.
#### Diamond ¹ Tin is part of the basic Minetest game (having migrated there from
Use: mainly for cutting machines moreores). It is found from elevation +8 downwards, with no
elevation-dependent variations in abundance beyond that point.
It is a common metal. Its main use in pure form is as a component
of electrical batteries. Apart from that its main purpose is
as the secondary ingredient in bronze (the base being copper), but bronze
is itself little used. Its abundance is well in excess of its usage,
so you will usually have a surplus of it.
Diamond is a precious gemstone. It is used moderately, mainly for reasons Zinc is supplied by technic. It is found from elevation +2 downwards,
connected to its extreme hardness. with no elevation-dependent variations in abundance beyond that point.
It is a common metal. Its main use is as the secondary ingredient
in brass (the base being copper), but brass is itself little used.
Its abundance is well in excess of its usage, so you will usually have
a surplus of it.
#### Gold ¹ Chromium is supplied by technic. It is found from elevation -100
Use: various downwards, with no elevation-dependent variations in abundance beyond
that point. It is a moderately common metal. Its main use is as the
secondary ingredient in stainless steel (the base being iron).
Generated below: -64m, more commonly below -256m Uranium is supplied by technic. It is found only from elevation -80 down
to -300; using it therefore requires one to mine above elevation -300 even
though deeper mining is otherwise more productive. It is a moderately
common metal, useful only for reasons related to radioactivity: it forms
the fuel for nuclear reactors, and is also one of the best radiation
shielding materials available. It is not difficult to find enough uranium
ore to satisfy these uses. Beware that the ore is slightly radioactive:
it will slightly harm you if you stand as close as possible to it.
It is safe when more than a meter away or when mined.
Gold is a precious metal. It is most notably used in electrical items due to Silver is supplied by the moreores mod. It is found from elevation -2
its combination of good conductivity and corrosion resistance. downwards, with no elevation-dependent variations in abundance beyond
that point. It is a semi-precious metal. It is little used, being most
notably used in electrical items due to its conductivity, being the best
conductor of all the pure elements.
#### Iron ¹ Gold is part of the basic Minetest game (having migrated there from
Use: multiple, mainly for alloys with carbon (coal). moreores). It is found from elevation -64 downwards, but is more
abundant from elevation -256 downwards. It is a precious metal. It is
little used, being most notably used in electrical items due to its
combination of good conductivity (third best of all the pure elements)
and corrosion resistance.
#### Lead Mithril is supplied by the moreores mod. It is found from elevation
Use: batteries, HV nuclear reactor layout -512 downwards, the deepest ceiling of any minable substance, with
no elevation-dependent variations in abundance beyond that point.
Generated below: 16m, more common below -128m It is a rare precious metal, and unlike all the other metals described
here it is entirely fictional, being derived from J. R. R. Tolkien's
#### Mese ¹
Use: various
Mese is a precious gemstone, and unlike diamond it is entirely fictional.
It is used in small quantities, wherever some magic needs to be imparted.
#### Mithril ²
Use: chests
Generated below: -512m, evenly common
Mithril is a fictional ore, being derived from J. R. R. Tolkien's
Middle-Earth setting. It is little used. Middle-Earth setting. It is little used.
#### Silver ² Mese is part of the basic Minetest game. It is found from elevation
Use: conductors -64 downwards. The ore is more abundant from elevation -256 downwards,
and from elevation -1024 downwards there are also occasional blocks of
solid mese (each yielding as much mese as nine blocks of ore). It is a
precious gemstone, and unlike diamond it is entirely fictional. It is
used in many recipes, though mainly not in large quantities, wherever
some magical quality needs to be imparted.
Generated below: -2m, evenly common Diamond is part of the basic Minetest game (having migrated there from
technic). It is found from elevation -128 downwards, but is more abundant
from elevation -256 downwards. It is a precious gemstone. It is used
moderately, mainly for reasons connected to its extreme hardness.
Silver is a semi-precious metal and is the best conductor of all the pure elements. ### rock ###
#### Tin ¹ In addition to the ores, there are multiple kinds of rock that need to be
Use: batteries, bronze mined in their own right, rather than for minerals. The rock types that
matter in technic are standard stone, desert stone, marble, and granite.
Tin is a common metal but is used rarely. Its abundance is well in excess Standard stone is part of the basic Minetest game. It is extremely
of its usage, so you will usually have a surplus of it. common. As in the basic game, when dug it yields cobblestone, which can
be cooked to turn it back into standard stone. Cobblestone is used in
recipes only for some relatively primitive machines. Standard stone is
used in a couple of machine recipes. These rock types gain additional
significance with technic because the grinder can be used to turn them
into dirt and sand. This, especially when combined with an automated
cobblestone generator, can be an easier way to acquire sand than
collecting it where it occurs naturally.
#### Uranium Desert stone is part of the basic Minetest game. It is found specifically
Use: nuclear reactor fuel in desert biomes, and only from elevation +2 upwards. Although it is
easily accessible, therefore, its quantity is ultimately quite limited.
It is used in a few recipes.
Depth: -80m until -300m, more commonly between -100m and -200m Marble is supplied by technic. It is found in dense clusters from
elevation -50 downwards. It has mainly decorative use, but also appears
in one machine recipe.
It is a moderately common metal, useful only for reasons related to radioactivity: Granite is supplied by technic. It is found in dense clusters from
it forms the fuel for nuclear reactors, and is also one of the best radiation elevation -150 downwards. It is much harder to dig than standard stone,
shielding materials available. so impedes mining when it is encountered. It has mainly decorative use,
but also appears in a couple of machine recipes.
Keep a safety distance of a meter to avoid being harmed by radiation. ### rubber ###
#### Zinc
Use: brass
Generated below: 2m, more commonly below -32m
Zinc only has a few uses but is a common metal.
### 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:
* Stone (plain)
* Cobblestone
* Desert Stone
#### Marble
Depth: -50m, evenly common
Marble is found in dense clusters and has mainly decorative use, but also
appears in one machine recipe.
#### Granite
Depth: -150m, evenly common
Granite is found in dense clusters and is much harder to dig than standard
stone. It has mainly decorative use, but also appears in a couple of
machine recipes.
#### Sulfur
Uses: battery box
Sulur is generated around some lava patches (caves).
### 2.3 Rubber
Rubber is a biologically-derived material that has industrial uses due Rubber is a biologically-derived material that has industrial uses due
to its electrical resistivity and its impermeability. In technic, it 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. is used in a few recipes, and it must be acquired by tapping rubber trees.
Rubber trees are provided by technic if the moretrees mod is not present. If you have the moretrees mod installed, the rubber trees you need
are those defined by that mod. If not, technic supplies a copy of the
moretrees rubber tree.
Extract raw latex from rubber using the "Tree Tap" tool. Punch/left-click the Extracting rubber requires a specific tool, a tree tap. Using the tree
tool on a rubber tree trunk to extract a lump of raw latex from the trunk. tap (by left-clicking) on a rubber tree trunk block extracts a lump of
Emptied trunks will regenerate at intervals of several minutes, which can be raw latex from the trunk. Each trunk block can be repeatedly tapped for
observed by its appearance. latex, at intervals of several minutes; its appearance changes to show
whether it is currently ripe for tapping. Each tree has several trunk
blocks, so several latex lumps can be extracted from a tree in one visit.
To obtain rubber from latex, alloy latex with coal dust. Raw latex isn't used directly. It must be vulcanized to produce finished
rubber. This can be performed by alloying the latex with coal dust.
## 3.0 Metal processing ### metal ###
Generally, each metal can exist in five forms:
* ore -> stone containing the lump Many of the substances important in technic are metals, and there is
* lump -> draw metal obtained by digging ("nuggets") a common pattern in how metals are handled. Generally, each metal can
* dust -> grinder output exist in five forms: ore, lump, dust, ingot, and block. With a couple of
* ingot -> melted/cooked lump or dust tricky exceptions in mods outside technic, metals are only *used* in dust,
* block -> placeable node ingot, and block forms. Metals can be readily converted between these
three forms, but can't be converted from them back to ore or lump forms.
Metals can be converted between dust, ingot and block, but can't be converted As in the basic Minetest game, a "lump" of metal is acquired directly by
from them back to ore or lump forms. digging ore, and will then be processed into some other form for use.
A lump is thus more akin to ore than to refined metal. (In real life,
metal ore rarely yields lumps ("nuggets") of pure metal directly.
More often the desired metal is chemically bound into the rock as an
oxide or some other compound, and the ore must be chemically processed
to yield pure metal.)
### Grinding Not all metals occur directly as ore. Generally, elemental metals (those
Ores can be processed as follows: consisting of a single chemical element) occur as ore, and alloys (those
consisting of a mixture of multiple elements) do not. In fact, if the
fictional mithril is taken to be elemental, this pattern is currently
followed perfectly. (It is not clear in the Middle-Earth setting whether
mithril is elemental or an alloy.) This might change in the future:
in real life some alloys do occur as ore, and some elemental metals
rarely occur naturally outside such alloys. Metals that do not occur
as ore also lack the "lump" form.
* ore -> lump (digging) -> ingot (melting) The basic Minetest game offers a single way to refine metals: cook a lump
* ore -> lump (digging) -> 2x dust (grinding) -> 2x ingot (melting) in a furnace to produce an ingot. With technic this refinement method
still exists, but is rarely used outside the early part of the game,
because technic offers a more efficient method once some machines have
been built. The grinder, available only in electrically-powered forms,
can grind a metal lump into two piles of metal dust. Each dust pile
can then be cooked into an ingot, yielding two ingots from one lump.
This doubling of material value means that you should only cook a lump
directly when you have no choice, mainly early in the game when you
haven't yet built a grinder.
At the expense of some energy consumption, the grinder can extract more material An ingot can also be ground back to (one pile of) dust. Thus it is always
from the lump, resulting in 2x dust which can be melted to two ingots in total. possible to convert metal between ingot and dust forms, at the expense
of some energy consumption. Nine ingots of a metal can be crafted into
a block, which can be used for building. The block can also be crafted
back to nine ingots. Thus it is possible to freely convert metal between
ingot and block forms, which is convenient to store the metal compactly.
Every metal has dust, ingot, and block forms.
### Alloying Alloying recipes in which a metal is the base ingredient, to produce a
Input: two ingredients of the same form - lump or dust 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. For example, brass can be produced
by alloying two copper ingots with one zinc ingot to make three brass
ingots, or by alloying two piles of copper dust with one pile of zinc
dust to make three piles of brass dust. The two ways of alloying produce
equivalent results.
Output: resulting alloy, as an ingot ### iron and its alloys ###
Example: 2x copper ingots + 1x zinc ingot -> 3x brass ingot (alloying) 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.
Note that grinding before alloying is the preferred method to gain more output. 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.
#### iron and its alloys 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.
Historically iron was the first metal whose working required processes of any In real-life history, the first form of iron to be refined was
metallurgical sophistication. The mod's mechanics around iron broadly imitate wrought iron, which is nearly pure iron, having low carbon content.
the historical progression of processes around it to get more variety. 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.
Notable alloys: 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.
* Wrought iron: <0.25% carbon Carbon steel, with intermediate carbon content, was developed much later,
* Resists shattering but is relatively soft. in Europe in the 17th century CE. It required a more sophisticated
* Known since: 1800 BC (approx.) process, because the blast furnace made it extremely difficult to achieve
* Cast iron: 2.1% to 4% carbon. a controlled carbon content. Tweaks of the blast furnace would sometimes
* Especially hard and rather corrosion-resistant produce an intermediate carbon content by luck, but the first processes to
* Known since: 1200 BC (approx.) reliably produce steel were based on removing almost all the carbon from
* Carbon steel: 0.25% to 2.1% carbon. pig iron and then explicitly mixing a controlled amount of carbon back in.
* Intermediate of the two above.
* Known since: 1600 AD (approx.)
Technic introduces a distinction based on the carbon content, and renames some In the game, the bloomery process is represented by ordinary cooking
items of the basic game accordingly. Iron and Steel are now distinguished. 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.
Notable references: 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.
* https://en.wikipedia.org/wiki/Iron Carbon steel is produced by a more regular in-game process: alloying
* https://en.wikipedia.org/wiki/Stainless_steel wrought iron with coal dust (which is essentially carbon). This bears
* ... plus many more. 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.
Processes: 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.
* Iron -> Wrought iron (melting) There's one more iron alloy in the game: stainless steel. It is managed
* Wrought iron -> Cast iron (melting) in a completely regular manner, created by alloying carbon steel with
* Wrought iron + coal dust -> Carbon steel (alloying) chromium.
* Carbon steel + coal dust -> Cast iron (alloying)
* Carbon steel + chromium -> Stainless steel (alloying)
Reversible processes: ### uranium enrichment ###
* Cast iron -> Wrought iron (melting)
* Carbon steel -> Wrought iron (melting)
Check your preferred crafting guide for more information.
### Uranium enrichment
When uranium is to be used to fuel a nuclear reactor, it is not 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 sufficient to merely isolate and refine uranium metal. It is necessary
@ -410,15 +523,35 @@ a post and adjacent concrete block.
industrial processes industrial processes
-------------------- --------------------
### Alloying ### alloying ###
In Technic, alloying is a way of combining items to create other items, In technic, alloying is a way of combining items to create other items,
distinct from standard crafting. Alloying always uses inputs of exactly distinct from standard crafting. Alloying always uses inputs of exactly
two distinct types, and produces a single output. 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.
Check your preferred crafting guide for more information. 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.
### Grinding, extracting, and compressing 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 are three distinct, but very Grinding, extracting, and compressing are three distinct, but very
similar, ways of converting one item into another. They are all quite similar, ways of converting one item into another. They are all quite
@ -492,17 +625,57 @@ 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 It recovers both components of binary metal/metal alloys. It can't
recover the carbon from steel or cast iron. recover the carbon from steel or cast iron.
Chests chests
------ ------
See [GitHub Wiki / Chests](https://github.com/minetest-mods/technic/wiki/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:
Features of extended chests: 1. wooden chest: 8&times;4 (32) slots
2. iron chest: 9&times;5 (45) slots
3. copper chest: 12&times;5 (60) slots
4. silver chest: 12&times;6 (72) slots
5. gold chest: 15&times;6 (90) slots
6. mithril chest: 15&times;6 (90) slots
* Larger storage space The iron and later chests have the ability to sort their contents,
* Labelling when commanded by a button in their interaction forms. Item types are
* Advanced item sorting 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.
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 radioactivity
------------- -------------
@ -640,44 +813,115 @@ 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 Tricky shine paths can also be addressed by just keeping players out of
the dangerous area. the dangerous area.
## Electrical power electrical power
----------------
Electrical networks in Technic are defined by a single tier (see below) Most machines in technic are electrically powered. To operate them it is
and consist of: necessary to construct an electrical power network. The network links
together power generators and power-consuming machines, connecting them
using power cables.
* 1x Switching Station (central management unit) There are three tiers of electrical networking: low voltage (LV),
* Any further stations are disabled automatically medium voltage (MV), and high voltage (HV). Each network must operate
* Electricity producers (PR) at a single voltage, and most electrical items are specific to a single
* Electricity consumers/receivers (RE) voltage. Generally, the machines of higher tiers are more powerful,
* Accumulators/batteries (BA) 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.
### Tiers 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.
* LV: Low Voltage. Low material costs but is slower. To be useful, an electrical network must connect at least one power
* MV: Medium Voltage. Higher processing speed. generator to at least one power-consuming machine. In addition to these
* HV: High Voltage. High material costs but is the fastest. 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.
Tiers can be converted from one to another using the Supply Converter node. Hovering over a network's switching station will show the aggregate energy
Its top connects to the input, the bottom to the output network. Configure supply and demand, which is useful for troubleshooting. Electrical energy
the input power by right-clicking it. is measured in "EU", and power (energy flow) in EU per second (EU/s).
Energy is shifted around a network instantaneously once per second.
### Machine upgrade slots 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).
Generally, machines of MV and HV tiers have two upgrade slots. When there are electrical networks of multiple tiers, it can be appealing
Only specific items will have any upgrading effect. The occupied slots do to generate energy on one tier and transfer it to another. The most
count, but not the actual stack size. 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.
**Type 1: Energy upgrade** powered machines
----------------
Consists of any battery item. Reduces the machine's power consumption ### powered machine tiers ###
regardless the charge of the item.
**Type 2: Tube upgrade** 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.
Consists of a control logic unit item. Ejects processed items into pneumatic ### powered machine upgrades ###
tubes for quicker processing.
### Machines + Tubes (pipeworks) 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 ###
Generally, powered machines of MV and HV tiers can work with pneumatic 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 tubes, and those of lower tiers cannot. (As an exception, the fuel-fired

View File

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

View File

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

View File

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

View File

@ -7,13 +7,6 @@ minetest.clear_craft({
type = "shapeless", type = "shapeless",
output = "default:bronze_ingot" output = "default:bronze_ingot"
}) })
-- Restore recipe for bronze block to ingots
minetest.register_craft({
output = "default:bronze_ingot 9",
recipe = {
{"default:bronzeblock"}
}
})
-- Accelerator tube -- Accelerator tube
if pipeworks.enable_accelerator_tube then if pipeworks.enable_accelerator_tube then
@ -174,6 +167,7 @@ minetest.register_craft({
}, },
}) })
minetest.register_craft({ minetest.register_craft({
output = "default:dirt 2", output = "default:dirt 2",
type = "shapeless", type = "shapeless",
@ -185,25 +179,3 @@ minetest.register_craft({
"group:sand", "group:sand",
}, },
}) })
minetest.register_craft({
output = "technic:rubber_goo",
type = "shapeless",
recipe = {
"technic:raw_latex",
"default:coal_lump",
"default:coal_lump",
"default:coal_lump",
"default:coal_lump",
"default:coal_lump",
"default:coal_lump",
"default:coal_lump",
"default:coal_lump",
},
})
minetest.register_craft({
output = "technic:rubber",
type = "cooking",
recipe = "technic:rubber_goo",
})

14
technic/depends.txt Normal file
View File

@ -0,0 +1,14 @@
default
pipeworks
technic_worldgen
basic_materials
bucket?
screwdriver?
mesecons?
mesecons_mvps?
digilines?
digiline_remote?
intllib?
unified_inventory?
vector_extras?
dye?

View File

@ -1,174 +1,41 @@
# technic API This file is fairly incomplete. Help is welcome.
This file documents the functions within the technic modpack for use in mods. Tiers
-----
The tier is a string, currently `"LV"`, `"MV"` and `"HV"` are supported.
[Switch to plaintext format](https://raw.githubusercontent.com/minetest-mods/technic/master/technic/doc/api.md) Network
-------
**Undocumented API may change at any time.** The network is the cable with the connected machine nodes. Currently the
switching station handles the network activity.
## Tiers
Tier are network types. List of pre-registered tiers:
* `"LV"`, Low Voltage
* `"MV"`, Medium Voltage
* `"HV"`, High Voltage
Available functions:
* `technic.register_tier(tier, description)`
* Registers a network type (tier)
* `tier`: string, short name (ex. `LV`)
* `description`: string, long name (ex. `Low Voltage`)
* See also `tiers`
## Cables
* `technic.register_cable(tier, size)`
* Registers an existing node as cable
* `tier`: string
* `size`: number, visual size of the wire
* `technic.get_cable_tier(nodename)`
* Retrieves the tier assigned to the provided node name
* `nodename`: string, name of the node
* Returns the tier (string) or `nil`
* `technic.is_tier_cable(nodename, tier)`
* Tells whether the node `nodename` is the cable of the tier `tier`.
* Short version of `technic.get_cable_tier(nodename) == tier`
* `technic.register_cable_tier(nodename, tier)`
* Register user defined cable to list of known tier cables.
* `nodename`: string, name of the node
* `tier`: string, tier name
## Machines
The machine type indicates the direction of power flow.
List of pre-registered machine types:
* `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"`: 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`: string, see #Tiers
* `nodename`: string, node name
* `machine_type`: string, following options are possible:
* `technic.receiver = "RE"`: Consumes energy
* `technic.producer = "PR"`: Provides energy
* `technic.battery = "BA"`: Energy storage
* See also `Machine types`
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.
### 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
* `technic.register_power_tool(itemname, max_charge)`
* Register or configure the maximal charge held by an existing item
* `craftitem`: string, item or node name
* `max_charge`: number, maximal EU capacity
## Helper functions
Unsorted functions:
Helper functions
----------------
* `technic.EU_string(num)` * `technic.EU_string(num)`
* Converts num to a human-readable string (see `pretty_num`) * Converts num to a human-readable string (see pretty_num)
and adds the `EU` unit and adds the `EU` unit
* Use this function when showing players energy values * Use this function when showing players energy values
* `technic.pretty_num(num)` * `technic.pretty_num(num)`
* Converts the number `num` to a human-readable string with SI prefixes * Converts the number `num` to a human-readable string with SI prefixes
* `technic.config:get(name)` * `technic.swap_node(pos, nodename)`
* Some configuration function * Same as `mintest.swap_node` but it only changes the nodename.
* `technic.tube_inject_item(pos, start_pos, velocity, item)` * It uses `minetest.get_node` before swapping to ensure the new nodename
* Same as `pipeworks.tube_inject_item` is not the same as the current one.
* `technic.get_or_load_node(pos)`
### Energy modifiers * If the mapblock is loaded, it returns the node at pos,
else it loads the chunk and returns `nil`.
* `technic.set_RE_wear(itemstack, item_load, max_charge)` * `technic.set_RE_wear(itemstack, item_load, max_charge)`
* Modifies the power tool wear of the given itemstack * If the `wear_represents` field in the item's nodedef is
* `itemstack`: ItemStack to modify `"technic_RE_charge"`, this function does nothing.
* `item_load`: number, used energy in EU
* `max_charge`: number, maximal EU capacity of the tool
* The itemdef field `wear_represents` must be set to `"technic_RE_charge"`,
otherwise this function will do nothing.
* Returns the modified itemstack
* `technic.refill_RE_charge(itemstack)` * `technic.refill_RE_charge(itemstack)`
* This function fully recharges an RE chargeable item. * This function fully recharges an RE chargeable item.
* If `technic.power_tools[itemstack:get_name()]` is `nil` (or `false`), this * If `technic.power_tools[itemstack:get_name()]` is `nil` (or `false`), this
function does nothing, else that value is the maximum charge. function does nothing, else that value is the maximum charge.
* The itemstack metadata is changed to contain the charge. * The itemstack metadata is changed to contain the charge.
* `technic.is_tier_cable(nodename, tier)`
### Node-specific * Tells whether the node `nodename` is the cable of the tier `tier`.
* `technic.get_or_load_node(pos)` * `technic.get_cable_tier(nodename)`
* If the mapblock is loaded, it returns the node at pos, * Returns the tier of the cable `nodename` or `nil`.
else it loads the chunk and returns `nil`.
* `technic.swap_node(pos, nodename)`
* Same as `mintest.swap_node` but it only changes the nodename.
* It uses `minetest.get_node` before swapping to ensure the new nodename
is not the same as the current one.
* `technic.trace_node_ray(pos, dir, range)` * `technic.trace_node_ray(pos, dir, range)`
* Returns an iteration function (usable in the for loop) to iterate over the * Returns an iteration function (usable in the for loop) to iterate over the
node positions along the specified ray. node positions along the specified ray.
@ -176,97 +43,95 @@ Unsorted functions:
* `technic.trace_node_ray_fat(pos, dir, range)` * `technic.trace_node_ray_fat(pos, dir, range)`
* Like `technic.trace_node_ray` but includes extra positions near the ray. * Like `technic.trace_node_ray` but includes extra positions near the ray.
* The node ray functions are used for mining lasers. * The node ray functions are used for mining lasers.
* `technic.config:get(name)`
* Some configuration function
* `technic.tube_inject_item(pos, start_pos, velocity, item)`
* Same as `pipeworks.tube_inject_item`
Registration functions
----------------------
* `technic.register_power_tool(itemname, max_charge)`
* Same as `technic.power_tools[itemname] = max_charge`
* This function makes the craftitem `itemname` chargeable.
* `technic.register_machine(tier, nodename, machine_type)`
* Same as `technic.machines[tier][nodename] = machine_type`
* Currently this is requisite to make technic recognize your node.
* See also `Machine types`
* `technic.register_tier(tier)`
* Same as `technic.machines[tier] = {}`
* See also `tiers`
## Item Definition fields ### Specific machines
Groups: * `technic.register_solar_array(data)`
* data is a table
* `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.
* `technic_<tier> = 1` Used itemdef fields
* Makes the node connect to the cables of the matching tier name -------------------
* `<tier>`: name of the tier, in lowercase (ex. `lv`) * groups:
* `technic_machine = 1` * `technic_<ltier> = 1` ltier is a tier in small letters; this group makes
* UNRELIABLE. Indicates whether the item or node belongs to technic the node connect to the cable(s) of the right tier.
* `connect_sides = {"top", "left", ...}` * `technic_machine = 1` Currently used for
* Extends the Minetest API. Indicates where the machine can be connected. * `connect_sides`
* In addition to the default use (see lua_api.txt), this tells where the
Additional definition fields: machine can be connected.
#
* `<itemdef>.wear_represents = "string"` #
* Specifies how the tool wear level is handled. Available modes: * `technic_run(pos, node)`
* `"mechanical_wear"`: represents physical damage * This function is currently used to update the node.
* `"technic_RE_charge"`: represents electrical charge
* `<itemdef>.technic_run = function(pos, node) ...`
* This callback is used to update the node.
Modders have to manually change the information about supply etc. in the Modders have to manually change the information about supply etc. in the
node metadata. 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`
Machine types
-------------
There are currently following types:
* `technic.receiver = "RE"` e.g. grinder
* `technic.producer = "PR"` e.g. solar panel
* `technic.producer_receiver = "PR_RE"` supply converter
* `technic.battery = "BA"` e.g. LV batbox
## Node Metadata fields Switching Station
-----------------
The switching station is the center of all power distribution on an electric
network.
The station 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.
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.
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.
### Node meta usage
Nodes connected to the network will have one or more of these parameters as meta Nodes connected to the network will have one or more of these parameters as meta
data: data:
* `<LV|MV|HV>_EU_supply` : Exists for PR and BA node types.
This is the EU value supplied by the node. Output
* `<LV|MV|HV>_EU_demand` : Exists for RE and BA node types.
This is the EU value the node requires to run. Output
* `<LV|MV|HV>_EU_input` : Exists for RE and BA node types.
This is the actual EU value the network can give the node. Input
* `<tier>_EU_supply` - direction: output The reason the LV|MV|HV type is prepended to meta data is because some machine
* For nodes registered as `PR` or `BA` tier could require several supplies to work.
* This is the EU value supplied by the node. This way the supplies are separated per network.
* `<tier>_EU_demand` - direction: output
* For nodes registered as `RE` or `BA` tier
* This is the EU value the node requires to run.
* `<tier>_EU_input` - direction: input
* For nodes registered as `RE` or `BA` tier
* This is the actual EU value the network can give the node.
`<tier>` corresponds to the tier name registered using
`technic.register_tier` (ex. `LV`). It is possible for the machine to depend on
multiple tiers (or networks).
## Manual: Network basics
The switching station is the center of all power distribution on an electric
network. This node is used to calculate the power supply of the network and
to distribute the power across nodes.
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).
As a thumb of rule, "EU" (energy unit) values are expressed in kW.
Network functionality:
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
Following functions are either no longer used by technic, or are planned to
be removed soon. Please update mods depending on technic accordingly.
* `technic.get_RE_item_load`
* Scales the tool wear to a certain numeric range
* `technic.set_RE_item_load`
* Scales a certain numeric range to the tool wear

View File

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

View File

@ -1,11 +1,7 @@
-- Minetest 0.4.7 mod: technic
-- namespace: technic -- namespace: technic
-- (c) 2012-2013 by RealBadAngel <mk@realbadangel.pl> -- (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() local load_start = os.clock()
technic = rawget(_G, "technic") or {} technic = rawget(_G, "technic") or {}
@ -20,17 +16,7 @@ technic.modpath = modpath
if rawget(_G, "intllib") then if rawget(_G, "intllib") then
technic.getter = intllib.Getter() technic.getter = intllib.Getter()
else else
-- 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"")else return"@"..o..n..c end end) end
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 end
local S = technic.getter local S = technic.getter

View File

@ -134,11 +134,6 @@ minetest.register_node("technic:machine_casing", {
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
}) })
minetest.register_craftitem("technic:rubber_goo", {
description = S("Rubber Goo"),
inventory_image = "technic_rubber_goo.png",
})
for p = 0, 35 do for p = 0, 35 do
local nici = (p ~= 0 and p ~= 7 and p ~= 35) and 1 or nil local nici = (p ~= 0 and p ~= 7 and p ~= 35) and 1 or nil
local psuffix = p == 7 and "" or p local psuffix = p == 7 and "" or p

View File

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

View File

@ -112,13 +112,10 @@ local function set_forcefield_formspec(meta)
else else
formspec = formspec.."button[0,1;5,1;mesecon_mode_0;"..S("Controlled by Mesecon Signal").."]" formspec = formspec.."button[0,1;5,1;mesecon_mode_0;"..S("Controlled by Mesecon Signal").."]"
end end
-- TODO: String replacement with %s will stop working with client-side translations
if meta:get_int("enabled") == 0 then if meta:get_int("enabled") == 0 then
formspec = formspec.."button[0,1.75;5,1;enable;".. formspec = formspec.."button[0,1.75;5,1;enable;"..S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
else else
formspec = formspec.."button[0,1.75;5,1;disable;".. formspec = formspec.."button[0,1.75;5,1;disable;"..S("%s Enabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
S("%s Enabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
end end
meta:set_string("formspec", formspec) meta:set_string("formspec", formspec)
end end

View File

@ -31,26 +31,24 @@ minetest.register_craft({
}) })
local function make_reactor_formspec(meta) local function make_reactor_formspec(meta)
local f = local f = "size[8,9]"..
"formspec_version[4]".. "label[0,0;"..S("Nuclear Reactor Rod Compartment").."]"..
"size[10.75,10.75]".. "list[current_name;src;2,1;3,2;]"..
"label[0.2,0.4;"..S("Nuclear Reactor Rod Compartment").."]".. "list[current_player;main;0,5;8,4;]"..
"list[current_name;src;1.5,1;3,2;]"..
"list[current_player;main;0.5,5.5;8,4;]"..
"listring[]".. "listring[]"..
"button[5.7,1;2,1;start;Start]".. "button[5.5,1.5;2,1;start;Start]"..
"checkbox[5.7,2.75;autostart;automatic Start;"..meta:get_string("autostart").."]" "checkbox[5.5,2.5;autostart;automatic Start;"..meta:get_string("autostart").."]"
if not digiline_remote_path then if not digiline_remote_path then
return f return f
end end
local digiline_enabled = meta:get_string("enable_digiline") local digiline_enabled = meta:get_string("enable_digiline")
f = f.."checkbox[1.5,3.75;enable_digiline;Enable Digiline channel;"..digiline_enabled.."]" f = f.."checkbox[0.5,2.8;enable_digiline;Enable Digiline;"..digiline_enabled.."]"
if digiline_enabled ~= "true" then if digiline_enabled ~= "true" then
return f return f
end end
return f.. return f..
"field[2,4.2;4.25,1;remote_channel;;${remote_channel}]" .. "button_exit[4.6,3.69;2,1;save;Save]"..
"button_exit[6.5,4.2;2,1;save;Save]" "field[1,4;4,1;remote_channel;Digiline Remote Channel;${remote_channel}]"
end end
local SS_OFF = 0 local SS_OFF = 0
@ -142,11 +140,8 @@ of a lead layer it will be converted to a lead layer.
--]] --]]
local function reactor_structure_badness(pos) local function reactor_structure_badness(pos)
local vm = VoxelManip() local vm = VoxelManip()
-- Blast-resistant Concrete Block layer outer positions
local pos1 = vector.subtract(pos, 3) local pos1 = vector.subtract(pos, 3)
local pos2 = vector.add(pos, 3) local pos2 = vector.add(pos, 3)
local MinEdge, MaxEdge = vm:read_from_map(pos1, pos2) local MinEdge, MaxEdge = vm:read_from_map(pos1, pos2)
local data = vm:get_data() local data = vm:get_data()
local area = VoxelArea:new({MinEdge=MinEdge, MaxEdge=MaxEdge}) local area = VoxelArea:new({MinEdge=MinEdge, MaxEdge=MaxEdge})
@ -162,19 +157,16 @@ local function reactor_structure_badness(pos)
for z = pos1.z, pos2.z do for z = pos1.z, pos2.z do
for y = pos1.y, pos2.y do for y = pos1.y, pos2.y do
for x = pos1.x, pos2.x do for x = pos1.x, pos2.x do
-- In the entire volume, make sure there is:
local cid = data[area:index(x, y, z)] local cid = data[area:index(x, y, z)]
if x == pos1.x or x == pos2.x or if x == pos1.x or x == pos2.x or
y == pos1.y or y == pos2.y or y == pos1.y or y == pos2.y or
z == pos1.z or z == pos2.z then z == pos1.z or z == pos2.z then
-- r=3 : Blast-resistant Concrete Block shell
if cid == c_blast_concrete then if cid == c_blast_concrete then
blast_layer = blast_layer + 1 blast_layer = blast_layer + 1
end end
elseif x == pos1.x+1 or x == pos2.x-1 or elseif x == pos1.x+1 or x == pos2.x-1 or
y == pos1.y+1 or y == pos2.y-1 or y == pos1.y+1 or y == pos2.y-1 or
z == pos1.z+1 or z == pos2.z-1 then z == pos1.z+1 or z == pos2.z-1 then
-- r=2 : Lead Block shell
if cid == c_lead then if cid == c_lead then
lead_layer = lead_layer + 1 lead_layer = lead_layer + 1
elseif cid == c_steel then elseif cid == c_steel then
@ -183,7 +175,6 @@ local function reactor_structure_badness(pos)
elseif x == pos1.x+2 or x == pos2.x-2 or elseif x == pos1.x+2 or x == pos2.x-2 or
y == pos1.y+2 or y == pos2.y-2 or y == pos1.y+2 or y == pos2.y-2 or
z == pos1.z+2 or z == pos2.z-2 then z == pos1.z+2 or z == pos2.z-2 then
-- r=1 : Water cooling
if cid == c_water_source or cid == c_water_flowing then if cid == c_water_source or cid == c_water_flowing then
water_layer = water_layer + 1 water_layer = water_layer + 1
end end
@ -193,8 +184,6 @@ local function reactor_structure_badness(pos)
end end
if steel_layer >= 96 then if steel_layer >= 96 then
-- Legacy: convert stainless steel to lead
-- Why don't we accept both without conversion?
for z = pos1.z+1, pos2.z-1 do for z = pos1.z+1, pos2.z-1 do
for y = pos1.y+1, pos2.y-1 do for y = pos1.y+1, pos2.y-1 do
for x = pos1.x+1, pos2.x-1 do for x = pos1.x+1, pos2.x-1 do
@ -217,7 +206,6 @@ local function reactor_structure_badness(pos)
if water_layer > 25 then water_layer = 25 end if water_layer > 25 then water_layer = 25 end
if lead_layer > 96 then lead_layer = 96 end if lead_layer > 96 then lead_layer = 96 end
if blast_layer > 216 then blast_layer = 216 end if blast_layer > 216 then blast_layer = 216 end
-- Amount of missing blocks
return (25 - water_layer) + (96 - lead_layer) + (216 - blast_layer) return (25 - water_layer) + (96 - lead_layer) + (216 - blast_layer)
end end
@ -229,33 +217,24 @@ end
local function start_reactor(pos, meta) local function start_reactor(pos, meta)
local correct_fuel_count = 6
local msg_fuel_missing = "Error: You need to insert " .. correct_fuel_count .. " pieces of Uranium Fuel."
if minetest.get_node(pos).name ~= "technic:hv_nuclear_reactor_core" then if minetest.get_node(pos).name ~= "technic:hv_nuclear_reactor_core" then
return msg_fuel_missing return false
end end
local inv = meta:get_inventory() local inv = meta:get_inventory()
if inv:is_empty("src") then if inv:is_empty("src") then
return msg_fuel_missing return false
end end
local src_list = inv:get_list("src") local src_list = inv:get_list("src")
local fuel_count = 0 local correct_fuel_count = 0
for _, src_stack in pairs(src_list) do for _, src_stack in pairs(src_list) do
if src_stack and src_stack:get_name() == fuel_type then if src_stack and src_stack:get_name() == fuel_type then
fuel_count = fuel_count + 1 correct_fuel_count = correct_fuel_count + 1
end end
end end
-- Check that the has the correct fuel -- Check that the reactor is complete and has the correct fuel
if fuel_count ~= correct_fuel_count then if correct_fuel_count ~= 6 or reactor_structure_badness(pos) ~= 0 then
return msg_fuel_missing return false
end end
-- Check that the reactor is complete
if reactor_structure_badness(pos) ~= 0 then
return "Error: The power plant seems to be built incorrectly."
end
meta:set_int("burn_time", 1) meta:set_int("burn_time", 1)
technic.swap_node(pos, "technic:hv_nuclear_reactor_core_active") technic.swap_node(pos, "technic:hv_nuclear_reactor_core_active")
meta:set_int("HV_EU_supply", power_supply) meta:set_int("HV_EU_supply", power_supply)
@ -263,8 +242,7 @@ local function start_reactor(pos, meta)
src_stack:take_item() src_stack:take_item()
inv:set_stack("src", idx, src_stack) inv:set_stack("src", idx, src_stack)
end end
return true
return nil
end end
@ -303,13 +281,13 @@ local function run(pos, node)
"fuel used", 6, true) "fuel used", 6, true)
end end
if meta:get_string("autostart") == "true" then if meta:get_string("autostart") == "true" then
if not start_reactor(pos, meta) then if start_reactor(pos, meta) then
return return
end end
end end
meta:set_int("HV_EU_supply", 0) meta:set_int("HV_EU_supply", 0)
meta:set_int("burn_time", 0) meta:set_int("burn_time", 0)
meta:set_string("infotext", S("@1 Idle", reactor_desc)) meta:set_string("infotext", S("%s Idle"):format(reactor_desc))
technic.swap_node(pos, "technic:hv_nuclear_reactor_core") technic.swap_node(pos, "technic:hv_nuclear_reactor_core")
meta:set_int("structure_accumulated_badness", 0) meta:set_int("structure_accumulated_badness", 0)
siren_clear(pos, meta) siren_clear(pos, meta)
@ -335,11 +313,11 @@ local nuclear_reactor_receive_fields = function(pos, formname, fields, sender)
meta:set_string("remote_channel", fields.remote_channel) meta:set_string("remote_channel", fields.remote_channel)
end end
if fields.start then if fields.start then
local start_error_msg = start_reactor(pos, meta) local b = start_reactor(pos, meta)
if not start_error_msg then if b then
minetest.chat_send_player(player_name, "Start successful") minetest.chat_send_player(player_name, "Start successful")
else else
minetest.chat_send_player(player_name, start_error_msg) minetest.chat_send_player(player_name, "Error")
end end
end end
if fields.autostart then if fields.autostart then
@ -407,11 +385,11 @@ local digiline_remote_def = function(pos, channel, msg)
melt_down_reactor(pos) melt_down_reactor(pos)
end end
elseif msg.command == "start" then elseif msg.command == "start" then
local start_error_msg = start_reactor(pos, meta) local b = start_reactor(pos, meta)
if not start_error_msg then if b then
digiline_remote.send_to_node(pos, channel, "Start successful", 6, true) digiline_remote.send_to_node(pos, channel, "Start successful", 6, true)
else else
digiline_remote.send_to_node(pos, channel, start_error_msg, 6, true) digiline_remote.send_to_node(pos, channel, "Error", 6, true)
end end
end end
end end

View File

@ -47,19 +47,14 @@ local function set_quarry_demand(meta)
local radius = meta:get_int("size") local radius = meta:get_int("size")
local diameter = radius*2 + 1 local diameter = radius*2 + 1
local machine_name = S("%s Quarry"):format("HV") local machine_name = S("%s Quarry"):format("HV")
local do_purge = meta:get_int("purge_on") == 1 if meta:get_int("enabled") == 0 or meta:get_int("purge_on") == 1 then
if meta:get_int("enabled") == 0 or do_purge then meta:set_string("infotext", S(meta:get_int("purge_on") == 1 and "%s purging cache" or "%s Disabled"):format(machine_name))
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) meta:set_int("HV_EU_demand", 0)
elseif meta:get_int("dug") == diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) then 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_string("infotext", S("%s Finished"):format(machine_name))
meta:set_int("HV_EU_demand", 0) meta:set_int("HV_EU_demand", 0)
else else
local infotext = meta:get_int("HV_EU_input") >= quarry_demand meta:set_string("infotext", S(meta:get_int("HV_EU_input") >= quarry_demand and "%s Active" or "%s Unpowered"):format(machine_name))
and S("%s Active") or S("%s Unpowered")
meta:set_string("infotext", infotext:format(machine_name))
meta:set_int("HV_EU_demand", quarry_demand) meta:set_int("HV_EU_demand", quarry_demand)
end end
end end
@ -110,40 +105,6 @@ local function quarry_handle_purge(pos)
end end
end end
-- Determines whether the quarry can dig the node at "pos"
-- "startpos" is located a few nodes above the quarry in South West direction (X-, Z-)
-- Returns the node to dig (to avoid double minetest.get_node lookup)
local function quarry_can_dig_node(startpos, pos, quarry_owner)
if minetest.is_protected(pos, quarry_owner) then
return nil
end
local node = technic.get_or_load_node(pos) or minetest.get_node(pos)
local def = minetest.registered_nodes[node.name] or {diggable=false}
-- doors mod among other thing does NOT like a nil digger...
local fakedigger = pipeworks.create_fake_player({
name = quarry_owner
})
if not def.diggable or (def.can_dig and not def.can_dig(pos, fakedigger)) then
return nil
end
-- Find airlike nodes on top of the current node. The entire Y column must be free.
for ay = pos.y+1, startpos.y do
local checkpos = {x=pos.x, y=ay, z=pos.z}
local checknode = technic.get_or_load_node(checkpos) or minetest.get_node(checkpos)
local cdef = minetest.registered_nodes[checknode.name] or {}
local is_kind_of_gas = cdef.buildable_to and cdef.sunlight_propagates and not cdef.walkable
and not cdef.diggable and (cdef.drawtype == "airlike" or cdef.drawtype == "glasslike")
if not is_kind_of_gas then
return nil
end
end
return node
end
local function quarry_run(pos, node) local function quarry_run(pos, node)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local inv = meta:get_inventory() local inv = meta:get_inventory()
@ -187,11 +148,35 @@ local function quarry_run(pos, node)
vector.new(0, -ry, 0)), vector.new(0, -ry, 0)),
vector.multiply(pdir, rp)), vector.multiply(pdir, rp)),
vector.multiply(qdir, rq)) vector.multiply(qdir, rq))
local can_dig = true
if can_dig and minetest.is_protected and minetest.is_protected(digpos, owner) then
can_dig = false
end
local dignode
if can_dig then
dignode = technic.get_or_load_node(digpos) or minetest.get_node(digpos)
local dignodedef = minetest.registered_nodes[dignode.name] or {diggable=false}
-- doors mod among other thing does NOT like a nil digger...
local fakedigger = pipeworks.create_fake_player({
name = owner
})
if not dignodedef.diggable or (dignodedef.can_dig and not dignodedef.can_dig(digpos, fakedigger)) then
can_dig = false
end
end
if can_dig then
for ay = startpos.y, digpos.y+1, -1 do
local checkpos = {x=digpos.x, y=ay, z=digpos.z}
local checknode = technic.get_or_load_node(checkpos) or minetest.get_node(checkpos)
if checknode.name ~= "air" then
can_dig = false
break
end
end
end
nd = nd + 1 nd = nd + 1
if can_dig then
local dignode = quarry_can_dig_node(startpos, digpos, owner)
if dignode then
minetest.remove_node(digpos) minetest.remove_node(digpos)
local drops = minetest.get_node_drops(dignode.name, "") local drops = minetest.get_node_drops(dignode.name, "")
for _, dropped_item in ipairs(drops) do for _, dropped_item in ipairs(drops) do

View File

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

View File

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

View File

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

View File

@ -24,6 +24,7 @@ local run = function(pos, node)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local eu_input = meta:get_int("LV_EU_input") local eu_input = meta:get_int("LV_EU_input")
local machine_name = S("%s Music Player"):format("LV") local machine_name = S("%s Music Player"):format("LV")
local machine_node = "technic:music_player"
local demand = 150 local demand = 150
local current_track = meta:get_int("current_track") local current_track = meta:get_int("current_track")

View File

@ -29,8 +29,8 @@ end
local run = function(pos, node) local run = function(pos, node)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local water_flow = 0 local water_flow = 0
local production_level local production_level = 0
local eu_supply local eu_supply = 0
local max_output = 4 * 45 -- keeping it around 180, little more than previous 150 :) local max_output = 4 * 45 -- keeping it around 180, little more than previous 150 :)
local positions = { local positions = {

View File

@ -30,8 +30,8 @@ end
local run = function(pos, node) local run = function(pos, node)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local water_flow = 0 local water_flow = 0
local production_level local production_level = 0
local eu_supply local eu_supply = 0
local max_output = 40 * 45 -- Generates 1800EU/s local max_output = 40 * 45 -- Generates 1800EU/s
local positions = { local positions = {

View File

@ -14,7 +14,20 @@ end
function technic_homedecor_node_is_owned(pos, placer) function technic_homedecor_node_is_owned(pos, placer)
local ownername = false local ownername = false
if type(isprotect) == "function" then -- glomie's protection mod if type(IsPlayerNodeOwner) == "function" then -- node_ownership mod
if HasOwner(pos, placer) then
if not IsPlayerNodeOwner(pos, placer:get_player_name()) then
if type(getLastOwner) == "function" then -- ...is an old version
ownername = getLastOwner(pos)
elseif type(GetNodeOwnerName) == "function" then -- ...is a recent version
ownername = GetNodeOwnerName(pos)
else
ownername = S("someone")
end
end
end
elseif type(isprotect) == "function" then -- glomie's protection mod
if not isprotect(5, pos, placer) then if not isprotect(5, pos, placer) then
ownername = S("someone") ownername = S("someone")
end end
@ -32,6 +45,7 @@ function technic_homedecor_node_is_owned(pos, placer)
end end
end end
local dirs1 = {20, 23, 22, 21}
local dirs2 = {9, 18, 7, 12} local dirs2 = {9, 18, 7, 12}
local technic_homedecor_rotate_and_place = function(itemstack, placer, pointed_thing) local technic_homedecor_rotate_and_place = function(itemstack, placer, pointed_thing)
@ -44,6 +58,7 @@ local technic_homedecor_rotate_and_place = function(itemstack, placer, pointed_t
local under = pointed_thing.under local under = pointed_thing.under
local pitch = placer:get_look_pitch() local pitch = placer:get_look_pitch()
local pname = minetest.get_node(under).name local pname = minetest.get_node(under).name
local node = minetest.get_node(above)
local fdir = minetest.dir_to_facedir(placer:get_look_dir()) local fdir = minetest.dir_to_facedir(placer:get_look_dir())
local wield_name = itemstack:get_name() local wield_name = itemstack:get_name()
@ -144,7 +159,7 @@ minetest.register_node('technic:homedecor_glowlight_half_yellow_active', {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
walkable = true, walkable = true,
light_source = minetest.LIGHT_MAX, light_source = LIGHT_MAX,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
groups = { snappy = 3, not_in_creative_inventory=1}, groups = { snappy = 3, not_in_creative_inventory=1},
@ -225,7 +240,7 @@ minetest.register_node('technic:homedecor_glowlight_quarter_yellow_active', {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
walkable = true, walkable = true,
light_source = minetest.LIGHT_MAX-1, light_source = LIGHT_MAX-1,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
groups = { snappy = 3, not_in_creative_inventory=1}, groups = { snappy = 3, not_in_creative_inventory=1},
@ -307,7 +322,7 @@ minetest.register_node('technic:homedecor_glowlight_half_white_active', {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
walkable = true, walkable = true,
light_source = minetest.LIGHT_MAX, light_source = LIGHT_MAX,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
groups = { snappy = 3, not_in_creative_inventory=1}, groups = { snappy = 3, not_in_creative_inventory=1},
@ -388,7 +403,7 @@ minetest.register_node('technic:homedecor_glowlight_quarter_white_active', {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
walkable = true, walkable = true,
light_source = minetest.LIGHT_MAX-1, light_source = LIGHT_MAX-1,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
groups = { snappy = 3, not_in_creative_inventory=1}, groups = { snappy = 3, not_in_creative_inventory=1},
@ -469,7 +484,7 @@ minetest.register_node('technic:homedecor_glowlight_small_cube_yellow_active', {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
walkable = true, walkable = true,
light_source = minetest.LIGHT_MAX-1, light_source = LIGHT_MAX-1,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
groups = { snappy = 3, not_in_creative_inventory=1}, groups = { snappy = 3, not_in_creative_inventory=1},
@ -550,7 +565,7 @@ minetest.register_node('technic:homedecor_glowlight_small_cube_white_active', {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
walkable = true, walkable = true,
light_source = minetest.LIGHT_MAX-1, light_source = LIGHT_MAX-1,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
groups = { snappy = 3, not_in_creative_inventory=1}, groups = { snappy = 3, not_in_creative_inventory=1},

View File

@ -36,8 +36,7 @@ technic.register_inductive_machine = function(name)
end end
-- Appliances: -- Appliances:
-- has_supply: pos of supply node if the appliance has a power radiator near -- has_supply: pos of supply node if the appliance has a power radiator near with sufficient power for the demand else ""
-- with sufficient power for the demand else ""
-- EU_demand: The power demand of the device. -- EU_demand: The power demand of the device.
-- EU_charge: Actual use. set to EU_demand if active==1 -- EU_charge: Actual use. set to EU_demand if active==1
-- active: set to 1 if the device is on -- active: set to 1 if the device is on
@ -178,6 +177,8 @@ minetest.register_abm({
-- The supply radius -- The supply radius
local rad = power_radius local rad = power_radius
local meta1 = nil
local pos1 = {}
local used_charge = 0 local used_charge = 0
-- Index all nodes within supply range -- Index all nodes within supply range

View File

@ -39,6 +39,7 @@ local run = function(pos, node)
local inv = meta:get_inventory() local inv = meta:get_inventory()
local eu_input = meta:get_int("MV_EU_input") local eu_input = meta:get_int("MV_EU_input")
local machine_name = S("%s Tool Workshop"):format("MV") local machine_name = S("%s Tool Workshop"):format("MV")
local machine_node = "technic:tool_workshop"
-- Setup meta data if it does not exist. -- Setup meta data if it does not exist.
if not eu_input then if not eu_input then

View File

@ -48,23 +48,20 @@ local function forceload_on(pos, meta)
end end
local function set_display(pos, meta) 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("infotext", S(meta:get_int("enabled") ~= 0 and "%s Enabled" or "%s Disabled"):format(desc))
meta:set_string("formspec", meta:set_string("formspec",
"size[5,3.5]".. "size[5,3.5]"..
"item_image[0,0;1,1;technic:admin_anchor]".. "item_image[0,0;1,1;technic:admin_anchor]"..
"label[1,0;"..ESC(desc).."]".. "label[1,0;"..minetest.formspec_escape(desc).."]"..
"label[0,1;"..ESC(S("Owner:").." "..meta:get_string("owner")).."]".. "label[0,1;"..minetest.formspec_escape(S("Owner:").." "..meta:get_string("owner")).."]"..
(meta:get_int("locked") == 0 and (meta:get_int("locked") == 0 and
"button[3,1;2,1;lock;"..ESC(S("Unlocked")).."]" or "button[3,1;2,1;lock;"..minetest.formspec_escape(S("Unlocked")).."]" or
"button[3,1;2,1;unlock;"..ESC(S("Locked")).."]").. "button[3,1;2,1;unlock;"..minetest.formspec_escape(S("Locked")).."]")..
"field[0.25,2.3;1,1;radius;"..ESC(S("Radius:"))..";"..meta:get_int("radius").."]".. "field[0.25,2.3;1,1;radius;"..minetest.formspec_escape(S("Radius:"))..";"..meta:get_int("radius").."]"..
(meta:get_int("enabled") == 0 and (meta:get_int("enabled") == 0 and
"button[3,2;2,1;enable;"..ESC(S("Disabled")).."]" or "button[3,2;2,1;enable;"..minetest.formspec_escape(S("Disabled")).."]" or
"button[3,2;2,1;disable;"..ESC(S("Enabled")).."]").. "button[3,2;2,1;disable;"..minetest.formspec_escape(S("Enabled")).."]")..
"label[0,3;"..ESC(S("Keeping %d/%d map blocks loaded"):format( "label[0,3;"..minetest.formspec_escape(S("Keeping %d/%d map blocks loaded"):format(#currently_forceloaded_positions(meta), #compute_forceload_positions(pos, meta))).."]")
#currently_forceloaded_positions(meta), #compute_forceload_positions(pos, meta)
)).."]")
end end
minetest.register_node("technic:admin_anchor", { minetest.register_node("technic:admin_anchor", {
@ -83,8 +80,7 @@ minetest.register_node("technic:admin_anchor", {
end, end,
can_dig = function (pos, player) can_dig = function (pos, player)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
return meta:get_int("locked") == 0 or return meta:get_int("locked") == 0 or (player and player:is_player() and player:get_player_name() == meta:get_string("owner"))
(player and player:is_player() and player:get_player_name() == meta:get_string("owner"))
end, end,
on_destruct = function (pos) on_destruct = function (pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
@ -103,11 +99,7 @@ minetest.register_node("technic:admin_anchor", {
forceload_off(meta) forceload_off(meta)
if fields.disable then meta:set_int("enabled", 0) end if fields.disable then meta:set_int("enabled", 0) end
if fields.enable then meta:set_int("enabled", 1) end if fields.enable then meta:set_int("enabled", 1) end
if fields.radius if fields.radius and string.find(fields.radius, "^[0-9]+$") and tonumber(fields.radius) < 256 then meta:set_int("radius", fields.radius) end
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 if meta:get_int("enabled") ~= 0 then
forceload_on(pos, meta) forceload_on(pos, meta)
end end

View File

@ -84,6 +84,8 @@ minetest.register_abm({
inv:set_size("src2", 0) inv:set_size("src2", 0)
end end
local recipe = nil
for i, name in pairs({ for i, name in pairs({
"fuel_totaltime", "fuel_totaltime",
"fuel_time", "fuel_time",

View File

@ -88,7 +88,6 @@ minetest.register_craft({
local function make_on(mark, length) local function make_on(mark, length)
return function(pos, node) return function(pos, node)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
local inv = meta:get_inventory() local inv = meta:get_inventory()
local dir = vector.new() local dir = vector.new()
if node.param2 == 3 then dir.x = 1 end if node.param2 == 3 then dir.x = 1 end
@ -103,9 +102,6 @@ local function make_on(mark, length)
minetest.check_for_falling(pos) minetest.check_for_falling(pos)
for i = 1, length do for i = 1, length do
place_pos = vector.add(place_pos, dir) place_pos = vector.add(place_pos, dir)
if owner ~= "" and minetest.is_protected(place_pos, owner) then
return
end
local place_node = minetest.get_node(place_pos) local place_node = minetest.get_node(place_pos)
deploy_node(inv, "slot"..i, place_pos, place_node, node) deploy_node(inv, "slot"..i, place_pos, place_node, node)
end end
@ -160,11 +156,6 @@ local function make_constructor(mark, length)
for i = 1, length do for i = 1, length do
inv:set_size("slot"..i, 1) inv:set_size("slot"..i, 1)
end end
meta:set_string("owner", "?")
end,
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("owner", (placer and placer:get_player_name() or "?"))
end, end,
can_dig = function(pos, player) can_dig = function(pos, player)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)

View File

@ -1,5 +1,7 @@
local S = technic.getter local S = technic.getter
frames = {}
local infinite_stacks = minetest.settings:get_bool("creative_mode") local infinite_stacks = minetest.settings:get_bool("creative_mode")
and minetest.get_modpath("unified_inventory") == nil and minetest.get_modpath("unified_inventory") == nil
@ -88,22 +90,22 @@ local function pos_in_list(l, pos)
return false return false
end end
local function table_empty(what) local function table_empty(table)
for _ in pairs(what) do for _, __ in pairs(table) do
return false return false
end end
return true return true
end end
local function add_table(what, toadd) local function add_table(table, toadd)
local i = 1 local i = 1
while true do while true do
local o = what[i] o = table[i]
if o == toadd then return end if o == toadd then return end
if o == nil then break end if o == nil then break end
i = i + 1 i = i + 1
end end
what[i] = toadd table[i] = toadd
end end
local function move_nodes_vect(poslist, vect, must_not_move, owner) local function move_nodes_vect(poslist, vect, must_not_move, owner)
@ -259,8 +261,8 @@ for zp = 0, 1 do
sunlight_propagates = true, sunlight_propagates = true,
frame_connect_all = function(nodename) frame_connect_all = function(nodename)
local l2 = {} l2 = {}
local l1 = { l1 = {
{ x = -1, y = 0, z = 0 }, { x = 1, y = 0, z = 0 }, { x = -1, y = 0, z = 0 }, { x = 1, y = 0, z = 0 },
{ x = 0, y = -1, z = 0 }, { x = 0, y = 1, z = 0 }, { x = 0, y = -1, z = 0 }, { x = 0, y = 1, z = 0 },
{ x = 0, y = 0, z = -1 }, { x = 0, y = 0, z = 1 } { x = 0, y = 0, z = -1 }, { x = 0, y = 0, z = 1 }
@ -309,7 +311,7 @@ for zp = 0, 1 do
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if node.name ~= "air" then if node.name ~= "air" then
if is_supported_node(node.name) then if is_supported_node(node.name) then
local obj = minetest.add_entity(pos, "technic:frame_entity") obj = minetest.add_entity(pos, "technic:frame_entity")
obj:get_luaentity():set_node({ name = itemstack:get_name() }) obj:get_luaentity():set_node({ name = itemstack:get_name() })
end end
else else
@ -347,8 +349,8 @@ for zp = 0, 1 do
end end
-- Run script hook -- Run script hook
local callback = nil local _, callback
for _, _ in ipairs(minetest.registered_on_placenodes) do for _, callback in ipairs(minetest.registered_on_placenodes) do
-- Copy pos and node because callback can modify them -- Copy pos and node because callback can modify them
local pos_copy = { x = pos.x, y = pos.y, z = pos.z } local pos_copy = { x = pos.x, y = pos.y, z = pos.z }
local newnode_copy = { name = def.name, param1 = 0, param2 = 0 } local newnode_copy = { name = def.name, param1 = 0, param2 = 0 }
@ -362,7 +364,7 @@ for zp = 0, 1 do
itemstack:take_item() itemstack:take_item()
end end
local obj = minetest.add_entity(pos, "technic:frame_entity") obj = minetest.add_entity(pos, "technic:frame_entity")
obj:get_luaentity():set_node({ name = node.name }) obj:get_luaentity():set_node({ name = node.name })
return itemstack return itemstack
@ -398,7 +400,21 @@ minetest.register_entity("technic:frame_entity", {
local pos = vector.round(self.object:getpos()) local pos = vector.round(self.object:getpos())
frames_pos[pos_to_string(pos)] = node.name frames_pos[pos_to_string(pos)] = node.name
local prop = { 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
prop = {
is_visible = true, is_visible = true,
textures = { node.name }, textures = { node.name },
} }
@ -573,7 +589,7 @@ local function connected(pos, c, adj)
end end
local function get_connected_nodes(pos) local function get_connected_nodes(pos)
local c = { pos } c = { pos }
local nodename = minetest.get_node(pos).name local nodename = minetest.get_node(pos).name
if frames_pos[pos_to_string(pos)] then if frames_pos[pos_to_string(pos)] then
nodename = frames_pos[pos_to_string(pos)] nodename = frames_pos[pos_to_string(pos)]
@ -679,7 +695,7 @@ local function swap_template(pos, new)
local saved_node = meta:get_string("saved_node") local saved_node = meta:get_string("saved_node")
meta:set_string("saved_node", "") meta:set_string("saved_node", "")
technic.swap_node(pos, new) technic.swap_node(pos, new)
meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("saved_node", saved_node) meta:set_string("saved_node", saved_node)
end end
@ -841,7 +857,7 @@ minetest.register_node("technic:template_disabled", {
on_destruct = template_on_destruct, on_destruct = template_on_destruct,
after_dig_node = template_drops, after_dig_node = template_drops,
on_punch = function(pos, node, puncher) on_punch = function(pos, node, puncher)
local _ = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
swap_template(pos, "technic:template_connector") swap_template(pos, "technic:template_connector")
end end
}) })

View File

@ -16,7 +16,7 @@ local function inject_items (pos)
if stack then if stack then
local item0=stack:to_table() local item0=stack:to_table()
if item0 then if item0 then
item0["count"] = 1 item0["count"] = "1"
technic.tube_inject_item(pos, pos, vector.new(0, -1, 0), item0) technic.tube_inject_item(pos, pos, vector.new(0, -1, 0), item0)
stack:take_item(1) stack:take_item(1)
inv:set_stack("main", i, stack) inv:set_stack("main", i, stack)
@ -61,9 +61,6 @@ local function set_injector_formspec(meta)
(is_stack and (is_stack and
"button[0,1;2,1;mode_item;"..S("Stackwise").."]" or "button[0,1;2,1;mode_item;"..S("Stackwise").."]" or
"button[0,1;2,1;mode_stack;"..S("Itemwise").."]").. "button[0,1;2,1;mode_stack;"..S("Itemwise").."]")..
(meta:get_int("public") == 1 and
"button[2,1;2,1;mode_private;"..S("Public").."]" or
"button[2,1;2,1;mode_public;"..S("Private").."]")..
"list[current_name;main;0,2;8,2;]".. "list[current_name;main;0,2;8,2;]"..
"list[current_player;main;0,5;8,4;]".. "list[current_player;main;0,5;8,4;]"..
"listring[]".. "listring[]"..
@ -120,15 +117,10 @@ minetest.register_node("technic:injector", {
return inv:is_empty("main") return inv:is_empty("main")
end, end,
on_receive_fields = function(pos, formanme, fields, sender) on_receive_fields = function(pos, formanme, fields, sender)
if minetest.is_protected(pos, sender:get_player_name()) then return end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if fields.mode_item then meta:set_string("mode", "single items") end if fields.mode_item then meta:set_string("mode", "single items") end
if fields.mode_stack then meta:set_string("mode", "whole stacks") end if fields.mode_stack then meta:set_string("mode", "whole stacks") end
if fields.mode_private then meta:set_int("public", 0) end
if fields.mode_public then meta:set_int("public", 1) end
if fields["fs_helpers_cycling:0:splitstacks"] if fields["fs_helpers_cycling:0:splitstacks"]
or fields["fs_helpers_cycling:1:splitstacks"] then or fields["fs_helpers_cycling:1:splitstacks"] then
if not pipeworks.may_configure(pos, sender) then return end if not pipeworks.may_configure(pos, sender) then return end

View File

@ -12,14 +12,14 @@ function technic.register_alloy_recipe(data)
end end
local recipes = { local recipes = {
{"technic:copper_dust 7", "technic:tin_dust", "technic:bronze_dust 8", 12}, {"technic:copper_dust 3", "technic:tin_dust", "technic:bronze_dust 4"},
{"default:copper_ingot 7", "default:tin_ingot", "default:bronze_ingot 8", 12}, {"default:copper_ingot 3", "default:tin_ingot", "default:bronze_ingot 4"},
{"technic:wrought_iron_dust 2", "technic:coal_dust", "technic:carbon_steel_dust 2", 6}, {"technic:wrought_iron_dust", "technic:coal_dust", "technic:carbon_steel_dust", 3},
{"technic:wrought_iron_ingot 2", "technic:coal_dust", "technic:carbon_steel_ingot 2", 6}, {"technic:wrought_iron_ingot", "technic:coal_dust", "technic:carbon_steel_ingot", 3},
{"technic:carbon_steel_dust 2", "technic:coal_dust", "technic:cast_iron_dust 2", 6}, {"technic:carbon_steel_dust", "technic:coal_dust", "technic:cast_iron_dust", 3},
{"technic:carbon_steel_ingot 2", "technic:coal_dust", "technic:cast_iron_ingot 2", 6}, {"technic:carbon_steel_ingot", "technic:coal_dust", "technic:cast_iron_ingot", 3},
{"technic:carbon_steel_dust 4", "technic:chromium_dust", "technic:stainless_steel_dust 5", 7.5}, {"technic:carbon_steel_dust 3", "technic:chromium_dust", "technic:stainless_steel_dust 4"},
{"technic:carbon_steel_ingot 4", "technic:chromium_ingot", "technic:stainless_steel_ingot 5", 7.5}, {"technic:carbon_steel_ingot 3", "technic:chromium_ingot", "technic:stainless_steel_ingot 4"},
{"technic:copper_dust 2", "technic:zinc_dust", "technic:brass_dust 3"}, {"technic:copper_dust 2", "technic:zinc_dust", "technic:brass_dust 3"},
{"default:copper_ingot 2", "technic:zinc_ingot", "basic_materials:brass_ingot 3"}, {"default:copper_ingot 2", "technic:zinc_ingot", "basic_materials:brass_ingot 3"},
{"default:sand 2", "technic:coal_dust 2", "technic:silicon_wafer"}, {"default:sand 2", "technic:coal_dust 2", "technic:silicon_wafer"},

View File

@ -192,10 +192,10 @@ function technic.register_battery_box(data)
end end
local run = function(pos, node) local run = function(pos, node)
local below = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z})
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local network_id = tonumber(meta:get_string(tier.."_network"))
if not technic.networks[network_id] then if not technic.is_tier_cable(below.name, tier) then
meta:set_string("infotext", S("%s Battery Box Has No Network"):format(tier)) meta:set_string("infotext", S("%s Battery Box Has No Network"):format(tier))
return return
end end
@ -304,14 +304,15 @@ function technic.register_battery_box(data)
drop = "technic:"..ltier.."_battery_box0", drop = "technic:"..ltier.."_battery_box0",
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local EU_upgrade, _ = 0 local EU_upgrade, tube_upgrade = 0, 0
if data.upgrade then if data.upgrade then
EU_upgrade, _ = technic.handle_machine_upgrades(meta) EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
end end
local max_charge = data.max_charge * (1 + EU_upgrade / 10) local max_charge = data.max_charge * (1 + EU_upgrade / 10)
local charge = meta:get_int("internal_EU_charge") local charge = meta:get_int("internal_EU_charge")
local cpercent = math.floor(charge / max_charge * 100) local cpercent = math.floor(charge / max_charge * 100)
local inv = meta:get_inventory() local inv = meta:get_inventory()
local node = minetest.get_node(pos)
meta:set_string("infotext", S("%s Battery Box"):format(tier)) meta:set_string("infotext", S("%s Battery Box"):format(tier))
meta:set_string("formspec", formspec..add_on_off_buttons(meta, ltier, cpercent)) meta:set_string("formspec", formspec..add_on_off_buttons(meta, ltier, cpercent))
meta:set_string("channel", ltier.."_battery_box"..minetest.pos_to_string(pos)) meta:set_string("channel", ltier.."_battery_box"..minetest.pos_to_string(pos))
@ -334,6 +335,7 @@ function technic.register_battery_box(data)
after_dig_node = technic.machine_after_dig_node, after_dig_node = technic.machine_after_dig_node,
on_receive_fields = function(pos, formname, fields, sender) on_receive_fields = function(pos, formname, fields, sender)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local nodename = minetest.get_node(pos).name
if fields.edit_channel then if fields.edit_channel then
minetest.show_formspec(sender:get_player_name(), minetest.show_formspec(sender:get_player_name(),
"technic:battery_box_edit_channel"..minetest.pos_to_string(pos), "technic:battery_box_edit_channel"..minetest.pos_to_string(pos),
@ -342,12 +344,12 @@ function technic.register_battery_box(data)
or fields["fs_helpers_cycling:0:split_dst_stacks"] or fields["fs_helpers_cycling:0:split_dst_stacks"]
or fields["fs_helpers_cycling:1:split_src_stacks"] or fields["fs_helpers_cycling:1:split_src_stacks"]
or fields["fs_helpers_cycling:1:split_dst_stacks"] then or fields["fs_helpers_cycling:1:split_dst_stacks"] then
meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if not pipeworks.may_configure(pos, sender) then return end if not pipeworks.may_configure(pos, sender) then return end
fs_helpers.on_receive_fields(pos, fields) fs_helpers.on_receive_fields(pos, fields)
local EU_upgrade, _ = 0 local EU_upgrade, tube_upgrade = 0, 0
if data.upgrade then if data.upgrade then
EU_upgrade, _ = technic.handle_machine_upgrades(meta) EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
end end
local max_charge = data.max_charge * (1 + EU_upgrade / 10) local max_charge = data.max_charge * (1 + EU_upgrade / 10)
local charge = meta:get_int("internal_EU_charge") local charge = meta:get_int("internal_EU_charge")
@ -409,25 +411,6 @@ minetest.register_on_player_receive_fields(
end 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
local item_meta = technic.get_stack_meta(itemstack)
return item_meta:get_int("technic:charge"), technic.power_tools[tool_name]
end
local function default_set_charge(itemstack, charge)
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 = technic.get_stack_meta(itemstack)
item_meta:set_int("technic:charge", charge)
end
function technic.charge_tools(meta, batt_charge, charge_step) function technic.charge_tools(meta, batt_charge, charge_step)
local inv = meta:get_inventory() local inv = meta:get_inventory()
if inv:is_empty("src") then if inv:is_empty("src") then
@ -435,18 +418,18 @@ function technic.charge_tools(meta, batt_charge, charge_step)
end end
local src_stack = inv:get_stack("src", 1) local src_stack = inv:get_stack("src", 1)
-- get callbacks local tool_name = src_stack:get_name()
local src_def = src_stack:get_definition() if not technic.power_tools[tool_name] then
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 return batt_charge, false
end 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 -- 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 if tool_charge >= item_max_charge then
return batt_charge, true return batt_charge, true
elseif batt_charge <= 0 then elseif batt_charge <= 0 then
@ -456,7 +439,9 @@ function technic.charge_tools(meta, batt_charge, charge_step)
charge_step = math.min(charge_step, item_max_charge - tool_charge) charge_step = math.min(charge_step, item_max_charge - tool_charge)
tool_charge = tool_charge + charge_step tool_charge = tool_charge + charge_step
batt_charge = batt_charge - charge_step batt_charge = batt_charge - charge_step
technic_set_charge(src_stack, tool_charge) technic.set_RE_wear(src_stack, tool_charge, item_max_charge)
src_meta.charge = tool_charge
src_stack:set_metadata(minetest.serialize(src_meta))
inv:set_stack("src", 1, src_stack) inv:set_stack("src", 1, src_stack)
return batt_charge, (tool_charge == item_max_charge) return batt_charge, (tool_charge == item_max_charge)
end end
@ -467,20 +452,21 @@ function technic.discharge_tools(meta, batt_charge, charge_step, max_charge)
if inv:is_empty("dst") then if inv:is_empty("dst") then
return batt_charge, false return batt_charge, false
end end
local src_stack = inv:get_stack("dst", 1) local srcstack = inv:get_stack("dst", 1)
local toolname = srcstack:get_name()
-- get callbacks if technic.power_tools[toolname] == nil then
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 return batt_charge, false
end 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 -- Do the discharging
local item_max_charge = technic.power_tools[toolname]
local tool_charge = src_meta.charge
if tool_charge <= 0 then if tool_charge <= 0 then
return batt_charge, true return batt_charge, true
elseif batt_charge >= max_charge then elseif batt_charge >= max_charge then
@ -490,8 +476,10 @@ function technic.discharge_tools(meta, batt_charge, charge_step, max_charge)
charge_step = math.min(charge_step, tool_charge) charge_step = math.min(charge_step, tool_charge)
tool_charge = tool_charge - charge_step tool_charge = tool_charge - charge_step
batt_charge = batt_charge + charge_step batt_charge = batt_charge + charge_step
technic_set_charge(src_stack, tool_charge) technic.set_RE_wear(srcstack, tool_charge, item_max_charge)
inv:set_stack("dst", 1, src_stack) src_meta.charge = tool_charge
srcstack:set_metadata(minetest.serialize(src_meta))
inv:set_stack("dst", 1, srcstack)
return batt_charge, (tool_charge == 0) return batt_charge, (tool_charge == 0)
end end

View File

@ -11,13 +11,6 @@ function technic.get_cable_tier(name)
return cable_tier[name] return cable_tier[name]
end end
function technic.register_cable_tier(name, tier)
assert(technic.machines[tier], "Tier does not exist")
assert(type(name) == "string", "Invalid node name")
cable_tier[name] = tier
end
local function check_connections(pos) local function check_connections(pos)
-- Build a table of all machines -- Build a table of all machines
local machines = {} local machines = {}
@ -67,27 +60,27 @@ local function clear_networks(pos)
local tier = network.tier local tier = network.tier
-- Actually add it to the (cached) network -- Actually add it to the (cached) network
-- !! IMPORTANT: ../switching_station.lua -> check_node_subp() must be kept in sync -- This is similar to check_node_subp
technic.cables[minetest.hash_node_position(pos)] = network_id technic.cables[minetest.hash_node_position(pos)] = network_id
pos.visited = 1 pos.visited = 1
if technic.is_tier_cable(node.name, tier) then if technic.is_tier_cable(name, tier) then
-- Found a cable
table.insert(network.all_nodes,pos) table.insert(network.all_nodes,pos)
elseif technic.machines[tier][node.name] then elseif technic.machines[tier][node.name] then
-- Found a machine meta:set_string(tier.."_network",minetest.pos_to_string(sw_pos))
local eu_type = technic.machines[tier][node.name] if technic.machines[tier][node.name] == technic.producer then
meta:set_string(tier.."_network", string.format("%.20g", network_id)) table.insert(network.PR_nodes,pos)
if eu_type == technic.producer then elseif technic.machines[tier][node.name] == technic.receiver then
table.insert(network.PR_nodes, pos) table.insert(network.RE_nodes,pos)
elseif eu_type == technic.receiver then elseif technic.machines[tier][node.name] == technic.producer_receiver then
table.insert(network.RE_nodes, pos) table.insert(network.PR_nodes,pos)
elseif eu_type == technic.producer_receiver then table.insert(network.RE_nodes,pos)
table.insert(network.PR_nodes, pos) elseif technic.machines[tier][node.name] == "SPECIAL" and
table.insert(network.RE_nodes, pos) (pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) and
elseif eu_type == technic.battery then from_below then
table.insert(network.BA_nodes, pos) table.insert(network.SP_nodes,pos)
elseif technic.machines[tier][node.name] == technic.battery then
table.insert(network.BA_nodes,pos)
end end
-- Note: SPECIAL (i.e. switching station) is not traversed!
end end
elseif dead_end and not placed then elseif dead_end and not placed then
-- Dead end removed, remove it from the network -- Dead end removed, remove it from the network

View File

@ -11,8 +11,8 @@ function technic.register_separating_recipe(data)
end end
local recipes = { local recipes = {
{ "technic:bronze_dust 8", "technic:copper_dust 7", "technic:tin_dust" }, { "technic:bronze_dust 4", "technic:copper_dust 3", "technic:tin_dust" },
{ "technic:stainless_steel_dust 5", "technic:wrought_iron_dust 4", "technic:chromium_dust" }, { "technic:stainless_steel_dust 4", "technic:wrought_iron_dust 3", "technic:chromium_dust" },
{ "technic:brass_dust 3", "technic:copper_dust 2", "technic:zinc_dust" }, { "technic:brass_dust 3", "technic:copper_dust 2", "technic:zinc_dust" },
{ "technic:chernobylite_dust", "default:sand", "technic:uranium3_dust" }, { "technic:chernobylite_dust", "default:sand", "technic:uranium3_dust" },
{ "default:dirt 4", "default:sand", "default:gravel", "default:clay_lump 2" }, { "default:dirt 4", "default:sand", "default:gravel", "default:clay_lump 2" },

View File

@ -74,7 +74,7 @@ function technic.send_items(pos, x_velocity, z_velocity, output_name)
if stack then if stack then
local item0 = stack:to_table() local item0 = stack:to_table()
if item0 then if item0 then
item0["count"] = 1 item0["count"] = "1"
technic.tube_inject_item(pos, pos, vector.new(x_velocity, 0, z_velocity), item0) technic.tube_inject_item(pos, pos, vector.new(x_velocity, 0, z_velocity), item0)
stack:take_item(1) stack:take_item(1)
inv:set_stack(output_name, i, stack) inv:set_stack(output_name, i, stack)
@ -84,6 +84,7 @@ function technic.send_items(pos, x_velocity, z_velocity, output_name)
end end
end end
function technic.smelt_item(meta, result, speed) function technic.smelt_item(meta, result, speed)
local inv = meta:get_inventory() local inv = meta:get_inventory()
meta:set_int("cook_time", meta:get_int("cook_time") + 1) meta:set_int("cook_time", meta:get_int("cook_time") + 1)
@ -111,6 +112,7 @@ function technic.handle_machine_pipeworks(pos, tube_upgrade, send_function)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local pos1 = vector.new(pos) local pos1 = vector.new(pos)
local x_velocity = 0 local x_velocity = 0
local z_velocity = 0 local z_velocity = 0

View File

@ -21,57 +21,27 @@ local recipes = {
{"technic:uranium35_ingot 5", "technic:uranium_fuel"}, {"technic:uranium35_ingot 5", "technic:uranium_fuel"},
} }
if minetest.get_modpath("everness") then
local everness_sand_to_sandstone_recipes = {
{"everness:coral_deep_ocean_sand 2", "everness:coral_deep_ocean_sandstone_block"},
{"everness:coral_sand 2", "everness:coral_sandstone"},
{"everness:coral_white_sand 2", "everness:coral_white_sandstone"},
{"everness:crystal_forest_deep_ocean_sand 2", "everness:crystal_forest_deep_ocean_sandstone_block"},
{"everness:crystal_sand 2", "everness:crystal_sandstone"},
{"everness:cursed_lands_deep_ocean_sand 2", "everness:cursed_lands_deep_ocean_sandstone_block"},
{"everness:cursed_sand 2", "everness:cursed_sandstone_block"},
{"everness:mineral_sand 2", "everness:mineral_sandstone"},
}
for _, data in ipairs(everness_sand_to_sandstone_recipes) do
table.insert(recipes, {data[1], data[2]})
end
end
-- defuse the default sandstone recipe, since we have the compressor to take over in a more realistic manner -- defuse the default sandstone recipe, since we have the compressor to take over in a more realistic manner
local crafts_to_clear = { minetest.clear_craft({
"default:desert_sand",
"default:sand",
"default:silver_sand"
}
if minetest.get_modpath("everness") then
local everness_crafts_to_clear = {
"everness:coral_sand",
"everness:coral_forest_deep_ocean_sand",
"everness:coral_white_sand",
"everness:crystal_sand",
"everness:cursed_sand",
"everness:cursed_lands_deep_ocean_sand",
"everness:crystal_forest_deep_ocean_sand",
"everness:mineral_sand",
}
for _, sand_name in ipairs(everness_crafts_to_clear) do
table.insert(crafts_to_clear, sand_name)
end
end
for _, sand_name in ipairs(crafts_to_clear) do
minetest.clear_craft({
type = "shaped",
recipe = { recipe = {
{sand_name, sand_name}, {"default:sand", "default:sand"},
{sand_name, sand_name}, {"default:sand", "default:sand"},
}, },
}) })
end minetest.clear_craft({
recipe = {
{"default:desert_sand", "default:desert_sand"},
{"default:desert_sand", "default:desert_sand"},
},
})
minetest.clear_craft({
recipe = {
{"default:silver_sand", "default:silver_sand"},
{"default:silver_sand", "default:silver_sand"},
},
})
for _, data in pairs(recipes) do for _, data in pairs(recipes) do
technic.register_compressor_recipe({input = {data[1]}, output = data[2]}) technic.register_compressor_recipe({input = {data[1]}, output = data[2]})
end end

View File

@ -162,6 +162,7 @@ function technic.register_generator(data)
fs_helpers.on_receive_fields(pos, fields) fs_helpers.on_receive_fields(pos, fields)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local form = generator_formspec
local form_buttons = "" local form_buttons = ""
if not string.find(node.name, ":lv_") then if not string.find(node.name, ":lv_") then
form_buttons = fs_helpers.cycling_button( form_buttons = fs_helpers.cycling_button(

View File

@ -23,8 +23,6 @@ local recipes = {
{"technic:sulfur_lump", "technic:sulfur_dust 2"}, {"technic:sulfur_lump", "technic:sulfur_dust 2"},
{"default:stone", "technic:stone_dust"}, {"default:stone", "technic:stone_dust"},
{"default:sand", "technic:stone_dust"}, {"default:sand", "technic:stone_dust"},
{"default:desert_sand", "technic:stone_dust"},
{"default:silver_sand", "technic:stone_dust"},
-- Other -- Other
{"default:cobble", "default:gravel"}, {"default:cobble", "default:gravel"},
@ -36,17 +34,6 @@ local recipes = {
{"default:ice", "default:snowblock"}, {"default:ice", "default:snowblock"},
} }
if minetest.get_modpath("everness") then
table.insert(recipes, {"everness:coral_deep_ocean_sandstone_block", "everness:coral_deep_ocean_sand 2"})
table.insert(recipes, {"everness:coral_sandstone", "everness:coral_sand 2"})
table.insert(recipes, {"everness:coral_white_sandstone", "everness:coral_white_sand 2"})
table.insert(recipes, {"everness:crystal_forest_deep_ocean_sandstone_block", "everness:crystal_forest_deep_ocean_sand 2"})
table.insert(recipes, {"everness:crystal_sandstone", "everness:crystal_sand 2"})
table.insert(recipes, {"everness:cursed_lands_deep_ocean_sandstone_block", "everness:cursed_lands_deep_ocean_sand 2"})
table.insert(recipes, {"everness:cursed_sandstone_block", "everness:cursed_sand 2"})
table.insert(recipes, {"everness:mineral_sandstone", "everness:mineral_sand 2"})
end
-- defuse the sandstone -> 4 sand recipe to avoid infinite sand bugs (also consult the inverse compressor recipe) -- defuse the sandstone -> 4 sand recipe to avoid infinite sand bugs (also consult the inverse compressor recipe)
minetest.clear_craft({ minetest.clear_craft({
recipe = { recipe = {
@ -64,15 +51,6 @@ minetest.clear_craft({
}, },
}) })
if minetest.get_modpath("everness") then
minetest.clear_craft({
recipe = {
{"everness:mineral_sandstone"}
},
})
-- Currently (2024-03-09), there seem to be no reverse recipes for any of the other everness sandstones.
end
if minetest.get_modpath("farming") then if minetest.get_modpath("farming") then
table.insert(recipes, {"farming:seed_wheat", "farming:flour 1"}) table.insert(recipes, {"farming:seed_wheat", "farming:flour 1"})
end end
@ -94,10 +72,6 @@ if minetest.get_modpath("homedecor") then
table.insert(recipes, {"home_decor:brass_ingot", "technic:brass_dust 1"}) table.insert(recipes, {"home_decor:brass_ingot", "technic:brass_dust 1"})
end end
if minetest.get_modpath("everness") then
table.insert(recipes, {"everness:pyrite_lump", "technic:pyrite_dust 2"})
end
for _, data in pairs(recipes) do for _, data in pairs(recipes) do
technic.register_grinder_recipe({input = {data[1]}, output = data[2]}) technic.register_grinder_recipe({input = {data[1]}, output = data[2]})
end end
@ -146,9 +120,6 @@ if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
register_dust("Kalite", nil) register_dust("Kalite", nil)
register_dust("Talinite", "glooptest:talinite_ingot") register_dust("Talinite", "glooptest:talinite_ingot")
end end
if minetest.get_modpath("everness") then
register_dust("Pyrite", "everness:pyrite_ingot")
end
for p = 0, 35 do for p = 0, 35 do
local nici = (p ~= 0 and p ~= 7 and p ~= 35) and 1 or nil local nici = (p ~= 0 and p ~= 7 and p ~= 35) and 1 or nil

View File

@ -1,5 +1,6 @@
local S = technic.getter local S = technic.getter
local moretrees = minetest.get_modpath("moretrees") local moretrees = minetest.get_modpath("moretrees")
local mesecons_materials = minetest.get_modpath("mesecons_materials")
local dye = minetest.get_modpath("dye") local dye = minetest.get_modpath("dye")
-- sawdust, the finest wood/tree grinding -- sawdust, the finest wood/tree grinding

View File

@ -39,8 +39,6 @@ function technic.register_base_machine(data)
local tier = data.tier local tier = data.tier
local ltier = string.lower(tier) local ltier = string.lower(tier)
data.modname = data.modname or minetest.get_current_modname()
local groups = {cracky = 2, technic_machine = 1, ["technic_"..ltier] = 1} local groups = {cracky = 2, technic_machine = 1, ["technic_"..ltier] = 1}
if data.tube then if data.tube then
groups.tubedevice = 1 groups.tubedevice = 1
@ -84,7 +82,7 @@ function technic.register_base_machine(data)
local eu_input = meta:get_int(tier.."_EU_input") local eu_input = meta:get_int(tier.."_EU_input")
local machine_desc_tier = machine_desc:format(tier) local machine_desc_tier = machine_desc:format(tier)
local machine_node = data.modname..":"..ltier.."_"..machine_name local machine_node = "technic:"..ltier.."_"..machine_name
local machine_demand = data.demand local machine_demand = data.demand
-- Setup meta data if it does not exist. -- Setup meta data if it does not exist.
@ -159,15 +157,15 @@ function technic.register_base_machine(data)
tentry = "" tentry = ""
end end
minetest.register_node(data.modname..":"..ltier.."_"..machine_name, { minetest.register_node("technic:"..ltier.."_"..machine_name, {
description = machine_desc:format(tier), description = machine_desc:format(tier),
tiles = { tiles = {
data.modname.."_"..ltier.."_"..machine_name.."_top.png"..tentry, "technic_"..ltier.."_"..machine_name.."_top.png"..tentry,
data.modname.."_"..ltier.."_"..machine_name.."_bottom.png"..tentry, "technic_"..ltier.."_"..machine_name.."_bottom.png"..tentry,
data.modname.."_"..ltier.."_"..machine_name.."_side.png"..tentry, "technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
data.modname.."_"..ltier.."_"..machine_name.."_side.png"..tentry, "technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
data.modname.."_"..ltier.."_"..machine_name.."_side.png"..tentry, "technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
data.modname.."_"..ltier.."_"..machine_name.."_front.png" "technic_"..ltier.."_"..machine_name.."_front.png"
}, },
paramtype2 = "facedir", paramtype2 = "facedir",
groups = groups, groups = groups,
@ -209,10 +207,9 @@ function technic.register_base_machine(data)
after_place_node = data.tube and pipeworks.after_place, after_place_node = data.tube and pipeworks.after_place,
after_dig_node = technic.machine_after_dig_node, after_dig_node = technic.machine_after_dig_node,
on_receive_fields = function(pos, formname, fields, sender) on_receive_fields = function(pos, formname, fields, sender)
if fields.quit then return end local node = minetest.get_node(pos)
if not pipeworks.may_configure(pos, sender) then return end if not pipeworks.may_configure(pos, sender) then return end
fs_helpers.on_receive_fields(pos, fields) fs_helpers.on_receive_fields(pos, fields)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local form_buttons = "" local form_buttons = ""
if not string.find(node.name, ":lv_") then if not string.find(node.name, ":lv_") then
@ -230,18 +227,18 @@ function technic.register_base_machine(data)
end, end,
}) })
minetest.register_node(data.modname..":"..ltier.."_"..machine_name.."_active",{ minetest.register_node("technic:"..ltier.."_"..machine_name.."_active",{
description = machine_desc:format(tier), description = machine_desc:format(tier),
tiles = { tiles = {
data.modname.."_"..ltier.."_"..machine_name.."_top.png"..tentry, "technic_"..ltier.."_"..machine_name.."_top.png"..tentry,
data.modname.."_"..ltier.."_"..machine_name.."_bottom.png"..tentry, "technic_"..ltier.."_"..machine_name.."_bottom.png"..tentry,
data.modname.."_"..ltier.."_"..machine_name.."_side.png"..tentry, "technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
data.modname.."_"..ltier.."_"..machine_name.."_side.png"..tentry, "technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
data.modname.."_"..ltier.."_"..machine_name.."_side.png"..tentry, "technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
data.modname.."_"..ltier.."_"..machine_name.."_front_active.png" "technic_"..ltier.."_"..machine_name.."_front_active.png"
}, },
paramtype2 = "facedir", paramtype2 = "facedir",
drop = data.modname..":"..ltier.."_"..machine_name, drop = "technic:"..ltier.."_"..machine_name,
groups = active_groups, groups = active_groups,
connect_sides = data.connect_sides or connect_default, connect_sides = data.connect_sides or connect_default,
legacy_facedir_simple = true, legacy_facedir_simple = true,
@ -252,12 +249,11 @@ function technic.register_base_machine(data)
allow_metadata_inventory_take = technic.machine_inventory_take, allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move, allow_metadata_inventory_move = technic.machine_inventory_move,
technic_run = run, technic_run = run,
technic_disabled_machine_name = data.modname..":"..ltier.."_"..machine_name, technic_disabled_machine_name = "technic:"..ltier.."_"..machine_name,
on_receive_fields = function(pos, formname, fields, sender) on_receive_fields = function(pos, formname, fields, sender)
if fields.quit then return end local node = minetest.get_node(pos)
if not pipeworks.may_configure(pos, sender) then return end if not pipeworks.may_configure(pos, sender) then return end
fs_helpers.on_receive_fields(pos, fields) fs_helpers.on_receive_fields(pos, fields)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local form_buttons = "" local form_buttons = ""
if not string.find(node.name, ":lv_") then if not string.find(node.name, ":lv_") then
@ -275,8 +271,8 @@ function technic.register_base_machine(data)
end, end,
}) })
technic.register_machine(tier, data.modname..":"..ltier.."_"..machine_name, technic.receiver) technic.register_machine(tier, "technic:"..ltier.."_"..machine_name, technic.receiver)
technic.register_machine(tier, data.modname..":"..ltier.."_"..machine_name.."_active", technic.receiver) technic.register_machine(tier, "technic:"..ltier.."_"..machine_name.."_active", technic.receiver)
end -- End registration end -- End registration

View File

@ -1,6 +1,4 @@
local have_ui = minetest.get_modpath("unified_inventory") local have_ui = minetest.get_modpath("unified_inventory")
local have_cg = minetest.get_modpath("craftguide")
local have_i3 = minetest.get_modpath("i3")
technic.recipes = { cooking = { input_size = 1, output_size = 1 } } technic.recipes = { cooking = { input_size = 1, output_size = 1 } }
function technic.register_recipe_type(typename, origdata) function technic.register_recipe_type(typename, origdata)
@ -8,25 +6,13 @@ function technic.register_recipe_type(typename, origdata)
for k, v in pairs(origdata) do data[k] = v end for k, v in pairs(origdata) do data[k] = v end
data.input_size = data.input_size or 1 data.input_size = data.input_size or 1
data.output_size = data.output_size or 1 data.output_size = data.output_size or 1
if data.output_size == 1 then if have_ui and unified_inventory.register_craft_type and data.output_size == 1 then
if have_ui and unified_inventory.register_craft_type then
unified_inventory.register_craft_type(typename, { unified_inventory.register_craft_type(typename, {
description = data.description, description = data.description,
width = data.input_size, width = data.input_size,
height = 1, height = 1,
}) })
end end
if have_cg and craftguide.register_craft_type then
craftguide.register_craft_type(typename, {
description = data.description,
})
end
if have_i3 then
i3.register_craft_type(typename, {
description = data.description,
})
end
end
data.recipes = {} data.recipes = {}
technic.recipes[typename] = data technic.recipes[typename] = data
end end
@ -73,27 +59,6 @@ local function register_recipe(typename, data)
width = 0, width = 0,
}) })
end end
if (have_cg or have_i3) and technic.recipes[typename].output_size == 1 then
local result = data.output
if (type(result)=="table") then
result = result[1]
end
local items = table.concat(data.input, ", ")
if have_cg and craftguide.register_craft then
craftguide.register_craft({
type = typename,
result = result,
items = {items},
})
end
if have_i3 then
i3.register_craft({
type = typename,
result = result,
items = {items},
})
end
end
end end
function technic.register_recipe(typename, data) function technic.register_recipe(typename, data)

View File

@ -56,6 +56,7 @@ function technic.register_solar_array(data)
}, },
on_construct = function(pos) on_construct = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local name = minetest.get_node(pos).name
meta:set_int(tier.."_EU_supply", 0) meta:set_int(tier.."_EU_supply", 0)
end, end,
technic_run = run, technic_run = run,

View File

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

View File

@ -45,12 +45,14 @@ minetest.register_node("technic:switching_station",{
meta:set_string("active", 1) meta:set_string("active", 1)
meta:set_string("channel", "switching_station"..minetest.pos_to_string(pos)) meta:set_string("channel", "switching_station"..minetest.pos_to_string(pos))
meta:set_string("formspec", "field[channel;Channel;${channel}]") meta:set_string("formspec", "field[channel;Channel;${channel}]")
local poshash = minetest.hash_node_position(pos)
technic.redundant_warn.poshash = nil technic.redundant_warn.poshash = nil
end, end,
after_dig_node = function(pos) after_dig_node = function(pos)
minetest.forceload_free_block(pos) minetest.forceload_free_block(pos)
pos.y = pos.y - 1 pos.y = pos.y - 1
minetest.forceload_free_block(pos) minetest.forceload_free_block(pos)
local poshash = minetest.hash_node_position(pos)
technic.redundant_warn.poshash = nil technic.redundant_warn.poshash = nil
end, end,
on_receive_fields = function(pos, formname, fields, sender) on_receive_fields = function(pos, formname, fields, sender)
@ -98,10 +100,8 @@ local function flatten(map)
end end
-- Add a wire node to the LV/MV/HV network -- 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 function add_network_node(nodes, pos, network_id)
local node_id = hash_node_position(pos) local node_id = minetest.hash_node_position(pos)
technic.cables[node_id] = network_id technic.cables[node_id] = network_id
if nodes[node_id] then if nodes[node_id] then
return false return false
@ -117,48 +117,39 @@ local function add_cable_node(nodes, pos, network_id, queue)
end end
-- Generic function to add found connected nodes to the right classification array -- Generic function to add found connected nodes to the right classification array
-- !! IMPORTANT: register/cables.lua -> clear_networks() must be kept in sync local check_node_subp = function(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) technic.get_or_load_node(pos)
local name = minetest.get_node(pos).name local name = minetest.get_node(pos).name
if technic.is_tier_cable(name, network.tier) then if technic.is_tier_cable(name, tier) then
add_cable_node(network.all_nodes, pos, network_id, queue) add_cable_node(all_nodes, pos,network_id, queue)
return elseif machines[name] then
end
local eu_type = machines[name]
if not eu_type then
return
end
--dprint(name.." is a "..machines[name]) --dprint(name.." is a "..machines[name])
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
-- Normal tostring() does not have enough precision, neither does meta:set_int() meta:set_string(tier.."_network",minetest.pos_to_string(sw_pos))
-- Lua 5.1 bug: Cannot use hexadecimal notation for compression (see LuaJIT #911) if machines[name] == technic.producer then
meta:set_string(network.tier.."_network", string.format("%.20g", network_id)) add_network_node(PR_nodes, pos, network_id)
elseif machines[name] == technic.receiver then
if eu_type == technic.producer then add_network_node(RE_nodes, pos, network_id)
add_network_node(network.PR_nodes, pos, network_id) elseif machines[name] == technic.producer_receiver then
elseif eu_type == technic.receiver then add_network_node(PR_nodes, pos, network_id)
add_network_node(network.RE_nodes, pos, network_id) add_network_node(RE_nodes, pos, network_id)
elseif eu_type == technic.producer_receiver then elseif machines[name] == "SPECIAL" and
add_network_node(network.PR_nodes, pos, network_id) (pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) and
add_network_node(network.RE_nodes, pos, network_id) from_below then
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 -- Another switching station -> disable it
add_network_node(network.SP_nodes, pos, network_id) add_network_node(SP_nodes, pos, network_id)
meta:set_int("active", 0) meta:set_int("active", 0)
elseif machines[name] == technic.battery then
add_network_node(BA_nodes, pos, network_id)
end end
meta:set_int(network.tier.."_EU_timeout", 2) -- Touch node meta:set_int(tier.."_EU_timeout", 2) -- Touch node
end
end end
-- Traverse a network given a list of machines and a cable type name -- Traverse a network given a list of machines and a cable type name
local traverse_network = function(network, pos, machines, sw_pos, network_id, queue) local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, pos, machines, tier, sw_pos, network_id, queue)
local positions = { local positions = {
{x=pos.x+1, y=pos.y, z=pos.z}, {x=pos.x+1, y=pos.y, z=pos.z},
{x=pos.x-1, y=pos.y, z=pos.z}, {x=pos.x-1, y=pos.y, z=pos.z},
@ -167,7 +158,7 @@ local traverse_network = function(network, pos, machines, sw_pos, network_id, qu
{x=pos.x, y=pos.y, z=pos.z+1}, {x=pos.x, y=pos.y, z=pos.z+1},
{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 for i, cur_pos in pairs(positions) do
check_node_subp(network, cur_pos, machines, sw_pos, i == 3, network_id, queue) check_node_subp(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, cur_pos, machines, tier, sw_pos, i == 3, network_id, queue)
end end
end end
@ -178,51 +169,43 @@ local touch_nodes = function(list, tier)
end end
end end
local get_network = function(sw_pos, cable_pos, tier) local get_network = function(sw_pos, pos1, tier)
local network_id = minetest.hash_node_position(cable_pos) local network_id = minetest.hash_node_position(pos1)
local cached = technic.networks[network_id] local cached = technic.networks[network_id]
if cached and cached.tier == tier then if cached and cached.tier == tier then
-- Re-use cached system data
touch_nodes(cached.PR_nodes, tier) touch_nodes(cached.PR_nodes, tier)
touch_nodes(cached.BA_nodes, tier) touch_nodes(cached.BA_nodes, tier)
touch_nodes(cached.RE_nodes, tier) touch_nodes(cached.RE_nodes, tier)
for _, pos in ipairs(cached.SP_nodes) do for _, pos in ipairs(cached.SP_nodes) do
-- Disable all other switching stations (again)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_int("active", 0) meta:set_int("active", 0)
meta:set_string("active_pos", minetest.serialize(sw_pos))
end end
return cached.PR_nodes, cached.BA_nodes, cached.RE_nodes return cached.PR_nodes, cached.BA_nodes, cached.RE_nodes
end end
local PR_nodes = {}
local machines = technic.machines[tier] local BA_nodes = {}
local network = { local RE_nodes = {}
tier = tier, local SP_nodes = {}
PR_nodes = {}, local all_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 = {} local queue = {}
add_cable_node(network.all_nodes, cable_pos, network_id, queue) add_cable_node(all_nodes, pos1, network_id, queue)
while next(queue) do while next(queue) do
local to_visit = {} local to_visit = {}
for _, pos in ipairs(queue) do for _, pos in ipairs(queue) do
traverse_network(network, pos, machines, sw_pos, network_id, to_visit) traverse_network(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes,
pos, technic.machines[tier], tier, sw_pos, network_id, to_visit)
end end
queue = to_visit queue = to_visit
end end
PR_nodes = flatten(PR_nodes)
-- Convert { [hash] = pos, ... } to { pos, ... } BA_nodes = flatten(BA_nodes)
network.PR_nodes = flatten(network.PR_nodes) RE_nodes = flatten(RE_nodes)
network.BA_nodes = flatten(network.BA_nodes) SP_nodes = flatten(SP_nodes)
network.RE_nodes = flatten(network.RE_nodes) all_nodes = flatten(all_nodes)
network.SP_nodes = flatten(network.SP_nodes) technic.networks[network_id] = {tier = tier, all_nodes = all_nodes, SP_nodes = SP_nodes,
network.all_nodes = flatten(network.all_nodes) PR_nodes = PR_nodes, RE_nodes = RE_nodes, BA_nodes = BA_nodes}
technic.networks[network_id] = network return PR_nodes, BA_nodes, RE_nodes
return network.PR_nodes, network.BA_nodes, network.RE_nodes
end end
----------------------------------------------- -----------------------------------------------
@ -232,17 +215,19 @@ end
technic.powerctrl_state = true technic.powerctrl_state = true
minetest.register_chatcommand("powerctrl", { minetest.register_chatcommand("powerctrl", {
params = "[on/off]", params = "state",
description = "Enables or disables technic's switching station ABM", description = "Enables or disables technic's switching station ABM",
privs = { basic_privs = true }, privs = { basic_privs = true },
func = function(name, state) func = function(name, state)
technic.powerctrl_state = (state:trim():lower() == "on") if state == "on" then
minetest.chat_send_player(name, "Technic switching station: " .. technic.powerctrl_state = true
(technic.powerctrl_state and "on" or "off")) else
technic.powerctrl_state = false
end
end end
}) })
-- Run `technic_run` on all nodes in the power grid -- Run all the nodes
local function run_nodes(list, run_stage) local function run_nodes(list, run_stage)
for _, pos in ipairs(list) do for _, pos in ipairs(list) do
technic.get_or_load_node(pos) technic.get_or_load_node(pos)
@ -258,23 +243,32 @@ end
minetest.register_abm({ minetest.register_abm({
nodenames = {"technic:switching_station"}, nodenames = {"technic:switching_station"},
label = "Switching Station", -- name for the Minetest mod profiler label = "Switching Station", -- allows the mtt profiler to profile this abm individually
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
if not technic.powerctrl_state then return end if not technic.powerctrl_state then return end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local meta1 local meta1 = nil
local PR_nodes, BA_nodes, RE_nodes local pos1 = {}
local PR_EU = 0 -- EUs from PR nodes
local BA_PR_EU = 0 -- EUs from BA nodes (discharching)
local BA_RE_EU = 0 -- EUs to BA nodes (charging)
local RE_EU = 0 -- EUs to RE nodes
local tier = ""
local PR_nodes
local BA_nodes
local RE_nodes
local machine_name = S("Switching Station") local machine_name = S("Switching Station")
-- Which kind of network are we on: -- Which kind of network are we on:
local cable_pos = {x=pos.x, y=pos.y-1, z=pos.z} pos1 = {x=pos.x, y=pos.y-1, z=pos.z}
--Disable if necessary --Disable if necessary
if meta:get_int("active") ~= 1 then if meta:get_int("active") ~= 1 then
minetest.forceload_free_block(pos) minetest.forceload_free_block(pos)
minetest.forceload_free_block(cable_pos) minetest.forceload_free_block(pos1)
meta:set_string("infotext",S("%s Already Present"):format(machine_name)) meta:set_string("infotext",S("%s Already Present"):format(machine_name))
local poshash = minetest.hash_node_position(pos) local poshash = minetest.hash_node_position(pos)
@ -286,18 +280,18 @@ minetest.register_abm({
return return
end end
local name = minetest.get_node(cable_pos).name local name = minetest.get_node(pos1).name
local tier = technic.get_cable_tier(name) local tier = technic.get_cable_tier(name)
if tier then if tier then
-- Forceload switching station -- Forceload switching station
minetest.forceload_block(pos) minetest.forceload_block(pos)
minetest.forceload_block(cable_pos) minetest.forceload_block(pos1)
PR_nodes, BA_nodes, RE_nodes = get_network(pos, cable_pos, tier) PR_nodes, BA_nodes, RE_nodes = get_network(pos, pos1, tier)
else else
--dprint("Not connected to a network") --dprint("Not connected to a network")
meta:set_string("infotext", S("%s Has No Network"):format(machine_name)) meta:set_string("infotext", S("%s Has No Network"):format(machine_name))
minetest.forceload_free_block(pos) minetest.forceload_free_block(pos)
minetest.forceload_free_block(cable_pos) minetest.forceload_free_block(pos1)
return return
end end
@ -350,16 +344,20 @@ minetest.register_abm({
end end
--dprint("Total RE demand:"..RE_eu_demand) --dprint("Total RE demand:"..RE_eu_demand)
-- Batteries -- Get all the power from the BA nodes
local BA_eu_supply, BA_eu_demand = 0, 0 local BA_eu_supply = 0
for _, pos1 in pairs(BA_nodes) do for _, pos1 in pairs(BA_nodes) do
meta1 = minetest.get_meta(pos1) meta1 = minetest.get_meta(pos1)
BA_eu_supply = BA_eu_supply + meta1:get_int(eu_supply_str) 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) BA_eu_demand = BA_eu_demand + meta1:get_int(eu_demand_str)
end end
-- Expose value for the supply converter
meta:set_int("ba_demand", BA_eu_demand)
--dprint("Total BA supply:"..BA_eu_supply)
--dprint("Total BA demand:"..BA_eu_demand) --dprint("Total BA demand:"..BA_eu_demand)
meta:set_string("infotext", S("@1. Supply: @2 Demand: @3", meta:set_string("infotext", S("@1. Supply: @2 Demand: @3",
@ -380,8 +378,8 @@ minetest.register_abm({
end end
-- Data that will be used by the power monitor -- Data that will be used by the power monitor
meta:set_int("supply", PR_eu_supply) meta:set_int("supply",PR_eu_supply)
meta:set_int("demand", RE_eu_demand) meta:set_int("demand",RE_eu_demand)
-- If the PR supply is enough for the RE demand supply them all -- If the PR supply is enough for the RE demand supply them all
if PR_eu_supply >= RE_eu_demand then if PR_eu_supply >= RE_eu_demand then
@ -471,17 +469,16 @@ minetest.register_abm({
for tier, machines in pairs(technic.machines) do for tier, machines in pairs(technic.machines) do
if machines[node.name] and switching_station_timeout_count(pos, tier) then if machines[node.name] and switching_station_timeout_count(pos, tier) then
local nodedef = minetest.registered_nodes[node.name] local nodedef = minetest.registered_nodes[node.name]
if nodedef then
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("%s Has No Network"):format(nodedef.description))
end
if nodedef and nodedef.technic_disabled_machine_name then if nodedef and nodedef.technic_disabled_machine_name then
node.name = nodedef.technic_disabled_machine_name node.name = nodedef.technic_disabled_machine_name
minetest.swap_node(pos, node) minetest.swap_node(pos, node)
end elseif nodedef and nodedef.technic_on_disable then
if nodedef and nodedef.technic_on_disable then
nodedef.technic_on_disable(pos, node) nodedef.technic_on_disable(pos, node)
end end
if nodedef then
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("%s Has No Network"):format(nodedef.description))
end
end end
end end
end, end,

View File

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

View File

@ -244,6 +244,7 @@ to be safe, and limits the range at which source/player interactions
need to be considered. need to be considered.
--]] --]]
local abdomen_offset = 1 local abdomen_offset = 1
local cache_scaled_shielding = {}
local rad_dmg_cutoff = 0.2 local rad_dmg_cutoff = 0.2
local radiated_players = {} local radiated_players = {}
@ -428,7 +429,7 @@ for _, state in pairs({"flowing", "source"}) do
liquidtype = state, liquidtype = state,
liquid_alternative_flowing = "technic:corium_flowing", liquid_alternative_flowing = "technic:corium_flowing",
liquid_alternative_source = "technic:corium_source", liquid_alternative_source = "technic:corium_source",
liquid_viscosity = 7, -- like lava liquid_viscosity = LAVA_VISC,
liquid_renewable = false, liquid_renewable = false,
damage_per_second = 6, damage_per_second = 6,
post_effect_color = {a=192, r=80, g=160, b=80}, post_effect_color = {a=192, r=80, g=160, b=80},

View File

@ -44,10 +44,7 @@ end
-- Wear down a tool depending on the remaining charge. -- Wear down a tool depending on the remaining charge.
function technic.set_RE_wear(itemstack, item_load, max_load) function technic.set_RE_wear(itemstack, item_load, max_load)
local def = minetest.registered_items[itemstack:get_name()] if (minetest.registered_items[itemstack:get_name()].wear_represents or "mechanical_wear") ~= "technic_RE_charge" then return itemstack end
if (def.wear_represents or "mechanical_wear") ~= "technic_RE_charge" then
return itemstack
end
local temp local temp
if item_load == 0 then if item_load == 0 then
temp = 0 temp = 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 775 B

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

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