405 Commits

Author SHA1 Message Date
488f80d950 Clean file frames.lua to make more readable
- "#(array)" replaced with "#array"
- "(a and b) or c" replaced with "a and b or c"
- Cleaned some other places with unnecessary parenthesis
- "a,b" replaced with "a, b"
- "a+b" replaced with "a + b" (and for all other binops)
- "{a, b, c}" replaced with "{ a, b, c }"
- "-n + a" replaced with "a - n"
- Removed trailing whitespace
- Blank lines added in some very dense places
- Very long lines broken into shorter lines
- Use modern functions like vector.new and vector.round
- Align with spaces instead of tabs
2018-08-25 12:24:58 +02:00
d74c250a40 Preserve active timers at frame move
Previously timers were not copied over to the new nodes when frames
move.  This lead to blinky plants from mesecons to stop working after a
platform has moved, and buttons getting stuck in their pressed state.

Now the timers state for active timers are copied from the old node
positions to the new node positions.
2018-08-25 12:24:58 +02:00
2e7859c35e New MV Hydro Machine (#412)
* New MV hydro with upgraded power

The LV hydro is easy to make giving lot of power. The New hydro MV will put a tier system to it; thereby giving more incentive to player to pursue MV hydro plus a little survival aspect. This is a result of [Detailed discussion which is here](https://github.com/minetest-mods/technic/issues/411). Thanks to VanessaE for a good talk and support and enthusiasm to make one :) This will now produce around 175 EU (in between 150-200, so basically average). The MV hydro will give 10x more power than this one. :)
2018-08-25 12:24:14 +02:00
86a04d860e manual.md: Corrections and straightening of facts (#406)
- There are manuals for all of the modpacks Technic depends on (possibly this is recent)
- Tin is now part of minetest_game
- Minor typo fixes
2018-08-25 12:22:18 +02:00
9b40d02fbd Revert get_3d to deprecated get3d for 0.4.x compatibility 2018-08-04 09:57:30 +02:00
d1b54a573c Use tin from MTG instead of moreores (#401)
Register tin dust unconditionally
2018-07-21 19:11:12 +02:00
f013d2dd1f Mining laser fixes (#421)
Do not remove air and group:hot nodes instead of using a fixed list
Abort mining when encountering an unknown node
Add random to the smoke puff particle
Set mining laser tool range to 0
2018-07-21 19:10:32 +02:00
80c6a14566 Tidy up ore registrations (#422) 2018-07-21 19:09:27 +02:00
fb93388f06 Replace deprecated invsize[] with size[] 2018-07-19 14:36:21 +02:00
41f175986d Show EU power values more readable (#424)
Add the EU_string helper function
In comparison to pretty_num it uses SI prefixes, adds "EU" (e.g. kEU) and rounds the number for readability
Add a constant_digit_count boolean setting
2018-07-16 17:26:39 +02:00
6af0376c23 Use a:iter instead of for loops for sulfur generation (#423) 2018-07-16 17:25:53 +02:00
0fcc7a14c2 Replace old nodeupdate() with new minetest.check_for_falling() (#391) 2018-07-16 17:25:43 +02:00
68fac3ed7b Fix wooden chest formspec (#429) 2018-07-15 12:28:34 +02:00
395089dfd8 Wrench: Allow picking up with protection_bypass privilege (#393)
This allows admins to move other players locked chests/etc without hassle (relocating flying chests).
2018-07-15 12:27:52 +02:00
6664714313 Skip interact check for fake players
Fixes crash related to pipeworks
default.can_interact_with_node is not official part of the API yet. Using it anyway..
2018-06-28 19:49:04 +02:00
c93bfefd9f machines/HV/quarry.lua: [modification] provide a basic digger object to can_dig callbacks to prevent nil object errors (#425)
Minetest game's doors mod was known to cause server errors when passed a nil digger in it's can_dig callback,
due to always attempting to invoke digger:get_player_name().
Fix this by providing a basic fake player which provides this method to can_dig callbacks.
(It should be noted that currently this fix causes doors to be undiggable by quarries.)
2018-05-19 22:06:00 +02:00
689766f15a Remove unused values (#407) 2018-02-17 11:00:15 -08:00
a5db87f0f1 Test local variable 'have_ui' before calling 'unified_inventory' (#368) 2018-02-16 17:32:47 -08:00
86fb981b44 Fix O(n^2) network traversal 2018-02-13 18:25:44 +01:00
215de5487b Fix redundant_warn 2018-01-13 10:30:22 +01:00
930c51eef9 chests: fix sort_inventory function 2018-01-07 09:56:55 +01:00
DS
37d49142cf supply_converter: avoid crashes caused by wrong digiline message types (#397) 2017-10-31 13:56:10 -04:00
DS
e056800cea nuclear_reactor: do not set structure_accumulated_badness to less than 0 2017-09-07 07:43:20 +02:00
a84b5f3b28 print warning to console if redundant switching station is found
and where it is

only prints the warning once per redundant station, per minetest
session. if there are multiple redundant stations on a network, digging
one should cause the warning to appear for the next one technic finds,
if it doesn't show them all right away.
2017-07-03 18:05:52 -04:00
9d5bd90b57 add chat command to allow disabling of switching station ABM
(for situations where a user creates a laggy machine on a public server, use
this to suspend power distribution until the machine is found and disabled)

`/powerctrl off` to disable
`/powerctrl on` to reenable

(actually, anything but "on" disables it)
2017-07-03 17:35:19 -04:00
16146231b8 don't place eg. chests without data 2017-07-03 17:35:19 -04:00
d4162be9a7 remove wooden chests redefinitions
they're incompatible with current minetest_game and do nothing useful anyway
2017-06-17 22:06:37 -04:00
db480011fb only try to clear/redefine recipes for teleport and accel tube
if they are enabled in pipeworks' config
2017-06-13 00:17:52 -04:00
4cc124ff9e Replace deprecated call to 'minetest.env' (#371) 2017-06-08 03:30:41 -04:00
DS
bf58c77316 digilinize nuclear_reactor (#341)
* start digilinizing

* add self 💥 destruction and co.

* add start button and command

* fix some things

* add possibility to disable nuclear reactor in formspec

* oops

* some style

* improve connectivity

* add protection
2017-06-05 11:02:05 -04:00
a495541c09 Actually reuse mapgen table (#365) 2017-06-05 10:59:16 -04:00
DS
1a75cd9254 add sulfur-lead crafting recipe(s) for battery (#353) 2017-06-05 10:56:51 -04:00
DS
51f9df2cf2 make some forcefield improvements (#344)
* mkae some forcefield improvements

* add emitter on_blast
2017-06-05 10:56:03 -04:00
DS
9167d4fc6f update wrench (#359) 2017-06-05 10:53:18 -04:00
844e2fad47 Add the sapling group to rubber_tree_sapling (#366)
Add the sapling group to Rubber Tree Sapling so that it can be used in
Mesecons recipes for glue and blinky plant.
2017-06-05 10:52:47 -04:00
e1bb29c338 Agrege la traduccion al español (#362) 2017-06-05 10:52:31 -04:00
you
987cc5a6a4 Add api documentation (#361) 2017-06-05 10:51:59 -04:00
83a4bb60ca Fix flowing corium textures (#364) 2017-06-05 10:51:24 -04:00
97e1c8b7f2 Replace deprecated method 'setting_getbool' with 'settings:get_bool' (#369) 2017-06-05 10:50:30 -04:00
DS
9cc1a78371 advanced cable plate placing (#357)
* advanced cable plate placing

* make also sneak possible

* add screwdriver support
2017-06-05 10:50:15 -04:00
42efc7e47c clarify battery box connections. 2017-04-17 15:03:30 -04:00
adc638bd8c document current behavior of hydro gen 2017-04-16 23:06:24 -04:00
557dc4db1b Battery boxes no longer connect to tubes from bottom
(since a power cable needs to go there)

items destined for "discharge" still come from the top, but items bound for the
"charge" slot must come in from the left, right or back
2017-04-14 05:16:14 -04:00
e65c8b7130 Don't allow constructor to operate if bad facedir (fixes #328)
Also, use "simple" screwdriver mode for "off" constructor, and disable screwdriver for "on" one.
2017-04-13 20:48:18 -04:00
69feeef0af use clear_craft to remove default sandstone recipe
get rid of the two grinder recipes from homedecor/fake_fire (obsolete)
2017-04-13 20:27:19 -04:00
fc2f6d8976 Generalize check for cable below battery box 2017-04-13 22:36:52 +02:00
06abe11dd0 check for cable plate under battery also 2017-04-13 16:25:42 -04:00
6b8011eba7 Fix fence nodebox (#346) 2017-04-13 13:12:46 -04:00
1d20af1bcb replace HV nuke reactor nodeboxes with comparable mesh model
model includes a flat extension on one "side" to fix #342

rotate the reactor with the screwdriver with shift-right-click before filling, to
line up the flat side with your cabling.  Note that the reactor doesn't actually
care which side the cable comes from.
2017-04-12 22:22:29 -04:00
7c11ff1876 LV fuel-fired gen should not have tube connection overlays 2017-04-12 21:04:37 -04:00
a34ea59105 LV batbox should show charge on all X/Z sides
(also, fixup some other texture defs for readability)
2017-04-12 20:29:22 -04:00
33455328bd Make batteries only charge/discharge from the bottom
(they were already supposed to but would leech charge from sideways neighbors too)
2017-04-12 20:21:20 -04:00
14e0c4c48c revise cable connection overlay (make copper part look smaller) 2017-04-12 18:57:56 -04:00
170d3e09c5 clean-up battery box images, make more consistent
added tube or cable entry overlays as appropriate.
deleted a couple of obsolete textures
2017-04-12 18:50:50 -04:00
DS
970f608078 use clear_craft (#339)
* use clear_craft

* fix it

* Update grinder_recipes.lua
2017-04-12 15:14:35 -04:00
39bfb76cfb Take Item from Cable Plate Stack on Place (#345)
(when not in Creative)
and
Change drop to recipe.
2017-04-12 15:13:39 -04:00
d2fb249d94 fix wrong toggle switch "on" img in chests 2017-04-11 20:57:23 -04:00
fab2c492c4 pipeworks has button on/off, button label, and button "base" cached
used them wherever possible
2017-04-11 19:19:29 -04:00
54004f4951 redo top/bottom textures for supply converter
delete back/bottom texture for power monitor
use "machine bottom" for bottom of force field generator
add cable connection overlay, use it on various machines' bottoms/sides, as appropriate
2017-04-11 08:48:16 -04:00
8479a8c984 add pipeworks tube overlays to self-contained injector
also, gave it paramtype2 = "facedir" and removed the front connection
for consistency with other machines
2017-04-11 08:17:56 -04:00
0e9caf069d add pipeworks tube overlay to top of quarry
(and get rid of obsolete inventorycube() image)
2017-04-11 08:09:53 -04:00
869d0597ef add pipeworks tube entry overlay to tool workshop 2017-04-11 07:57:45 -04:00
ca86550f26 added tube entry overlays to most MV machines 2017-04-11 07:54:00 -04:00
a3a959ab5e add pipeworks tube overlays to MV, HV battery boxes 2017-04-11 07:48:46 -04:00
3f8478086d fix crash in battery mod (missing meta check) 2017-04-11 07:45:31 -04:00
092ab7e738 added tube entry overlays to fuel-fired generators 2017-04-11 07:37:18 -04:00
b6d343e928 add pipeworks tube connection overlays to all chests
(only applies if pipeworks is installed, if not, nothing is added)
2017-04-11 07:15:59 -04:00
bdd45f161a fix broken ltier checks on MV/HV fuel-fired generators 2017-04-11 06:56:21 -04:00
5d05f59482 allow per-node stack splitting on all other standard machines
(default off)
2017-04-11 06:26:11 -04:00
a353a807bd allow per-injector stack split
(default off)
2017-04-11 05:36:39 -04:00
db0f8e04a1 fix wrong size of self-contained injector inv 2017-04-11 05:31:36 -04:00
64f38f423e tool workshop shouldn't ever allow stack splitting
(tools don't stack :) )
2017-04-11 05:25:25 -04:00
ceead2b5ab re-route tubes if active fuel-fired gen is dug (and can be) 2017-04-11 05:15:05 -04:00
4eaf48290f allow per-generator stack splitting
(default off)
2017-04-11 05:13:27 -04:00
11f20da744 allow per-chest stack splitting
(default off)
2017-04-11 04:41:26 -04:00
7244f86ee5 allow per-battery charge/discharge stack splitting
(default off for both)
2017-04-11 04:41:11 -04:00
af39221df9 only reject part of itemtack from chest/machine/etc., if possible
(e.g. if there's room for 50 of some item, and you send a stack of 99,
50 are added to the chest and a stack of 49 is rejected and sent
on to the next destination)
2017-04-09 20:35:11 -04:00
72c536c04e always set the EU level
don't wait for production = 0.

(if water is removed, that causes phantom output)
2017-04-09 14:07:50 -04:00
b67bca1277 Change noise_threshhold to noise_threshold.
The old name was a typo and is deprecated.
2017-04-05 00:10:10 -03:00
ef8bb38bfd Make forcefield controlable with digilines. 2017-04-04 23:58:02 -03:00
6c4e90d39c Add digiline support to supply converter. 2017-04-04 23:52:27 -03:00
4dda59da0c Add conductive plates.
These work exactly like cables, but are meant to be
used as floor for when the machine does not fill the
while cube.
2017-04-04 21:59:13 -03:00
338f3b6a99 Make battery box send information via digilines. 2017-04-01 16:47:34 -03:00
eb344ad804 perlin improvements
as suggested by @paramat
2017-03-31 22:01:00 -04:00
78f16c3e8e label all ABMs for profiler 2017-03-31 19:15:25 -04:00
9755127ffd Update mg.lua (#336) 2017-03-29 18:01:52 -04:00
b7cecd7f3d Zinc rareness FIX(?) (#333)
* Zinc rareness FIX(?)

I created the issue and i will fix it. But still idk if this really helps. (It helped me)
At least it will make it more common in -32 and 2 Y distance. To compare its like in between iron and coal i belive.

* Update oregen.lua
2017-03-28 13:18:49 -04:00
6abd857b3f Add digiline support to switching station.
Makes the switching station able to send supply and demand
via digilines.
2017-03-28 09:30:59 -03:00
383f7df22d change nodename for gloopblocks rainbow block (now "diagonal"), add support
for its aliased version of the former nyan cat block (10k density)
2017-03-26 00:40:53 -04:00
767f5346e9 add gloopblocks rainbow block radiation setting
(half that of a nyan/pbj block)
2017-03-22 19:25:00 -04:00
df15a5ee65 add radiation protection via pbj_pup blocks
same strength as nyan blocks
2017-03-22 19:25:00 -04:00
cb5e3e8ff4 raise radiation shielding values on nyan blocks
from 1000 --> 10000

This makes it possible to protect a corium source with a layer of nyan blocks,
and avoid damage outside roughly 6m from the wall.

Also, added alternate node name for nyan blocks
2017-03-22 19:24:52 -04:00
600fc6ff7e use unified dyes auto-color feature 2017-03-18 06:27:59 -04:00
f420aa4d37 Clarify shielding information (#318)
* Clarify shielding information

Clarify notes about shielding values and description of Lead
2017-03-17 16:29:37 -04:00
7d76ff8d38 Merge pull request #326 from numberZero/fix-bc-supply-converter
Add backward compatibility to the new supply converter
2017-03-17 16:26:15 -04:00
408128d800 Add backward compatibility to the new supply converter 2017-03-17 21:10:43 +03:00
2a7dbe0506 move the register_node calls out of the unifieddyes check
simplify a little
2017-03-17 03:10:08 -04:00
018d66f791 define insulator clips even if Unified Dyes is not installed
(just don't put UD-related stuff into their node defs)
2017-03-15 23:49:36 -04:00
6341ac9638 assume missing "enabled" key == enabled also.
(would signify supply converts in old maps)
2017-03-15 23:23:07 -04:00
0a701a0dcf Merge pull request #325 from cheapie/master
Add chernobylite dust
2017-03-15 21:10:08 -04:00
7ea645496d Add chernobylite dust
Made by grinding chernobylite blocks, can be centrifuged into sand and 0.3% fissile uranium dust.
2017-03-15 20:05:37 -05:00
10307f23a7 Do not run converters twice. 2017-03-15 19:00:22 -04:00
7d5329834d Fix supply converter bug 2017-03-15 19:00:22 -04:00
ae7625d9f7 use unified dyes on_construct handler
in fencepost-style cable clip to set 256-color palette meta key on place
2017-03-14 02:15:40 -04:00
0ad8012cd3 extranodes: Make unifieddyes dependency optional. 2017-03-13 00:20:41 -03:00
3ba5354f83 add recipes for insulator clips 2017-03-11 20:02:20 -05:00
bf3498b736 really add insulator clip model
(and fix .gitignore accordingly)
2017-03-11 11:17:13 -05:00
e5f40f5c39 Merge pull request #321 from cheapie/master
Don't require a full network recalculation to add or remove a dead end
2017-03-11 02:03:44 -05:00
c4acb7225a Don't require a full network recalculation to add or remove a dead end
A dead end (node with only one connection) can be simply added or removed from the network without needing to traverse the whole thing.
2017-03-11 00:57:52 -06:00
8b222bc66b add fence-like cable clip
to complement the block-sized one
2017-03-11 01:17:19 -05:00
9382558d82 add insulated cable clip/mount
(purely decorative, uses colorwallmounted mode)
2017-03-10 22:30:36 -05:00
343c7946d9 power monitor changes
New textures, uses facedir, connects from the back as well.
2017-03-10 14:15:38 -05:00
5b473927ca Merge pull request #320 from cheapie/master
Fixes for network calculation issues
2017-03-10 02:44:16 -05:00
088eea1e3b Fixes for network calculation issues
This fixes several issues:
* More than one switching station could become active on large networks
 - Switching stations now semi-permanently become disabled if another is present
 - Power monitors have been added to replace the function of "slave" switching stations, to discourage overuse of switching stations
* Networks did not reliably "split" when cutting a cable
 - I "may" have caused this issue, but I believe it is solved by this
* Machines did not run without a player near the switching station
 - Active switching stations now forceload themselves, and free the forceloaded block if disabled, dug, or disconnected
 - Machines are only loaded to run them (as before), so only one mapblock (or two if the bottom edge of the switching station is a mapblock boundary) is loaded
 - Cables are still only loaded during a full network recalculation
2017-03-10 01:35:58 -06:00
9cc5ad3d90 Delete origin
Fixes #319.
2017-03-10 02:23:26 -03:00
b4659d9356 Merge pull request #317 from Thomas--S/chest-bugfix
Update chests protection to current minetest_game
2017-03-07 11:09:13 -05:00
186f9b70ac Temporary fix for crash in constructor. 2017-03-06 23:02:39 -03:00
ec6354b6a5 Update chests protection to current minetest_game 2017-03-06 21:09:44 +01:00
67d5a88d05 Merge pull request #316 from Thomas--S/chest-bugfix
Fix chest bug
2017-03-06 14:35:27 -05:00
35da22fcd2 Fix chest bug 2017-03-06 20:32:18 +01:00
60b5ca5594 Merge pull request #308 from thatgraemeguy/mk3_drill_fix
Make mk3 drill in 3x3 mode drill nodes from top to bottom
2017-03-06 14:22:25 -05:00
dd580e7684 Merge pull request #307 from Thomas--S/patch-2
Update chest definitions to current minetest_game definitions
2017-03-06 14:21:05 -05:00
663d272870 Merge pull request #306 from Thomas--S/patch-1
Update has_locked_chest_privilege to current minetest_game function
2017-03-06 14:20:11 -05:00
32b6ca9816 Merge pull request #298 from t4im/fix/quarry_loops
Mitigate server freezes due to item-transportation loops with quarries.
2017-03-06 14:11:40 -05:00
05dfc14fdb Merge pull request #297 from t4im/fix/drill_pointed_thing
Remove reading of undefined global to fix drill drilling pointed_thing.above in combination with other badly coded mods.
2017-03-06 14:08:06 -05:00
314d8c6c23 Merge pull request #288 from numberZero/control-supply_converter
Supply converter control
2017-03-06 14:07:12 -05:00
8596ca7c19 Merge pull request #283 from ghost/patch-1
Updated Italian locale
2017-03-06 14:01:03 -05:00
d26797d9de Merge pull request #272 from veikk0/master
Replace nuclear reactor alarm sound
2017-03-06 13:59:58 -05:00
ed2aab46e1 Merge pull request #258 from mrsteyk/patch-1
Zinc is too rare!!! It is an issue!
2017-03-06 13:56:38 -05:00
e3b33e21c7 Merge pull request #314 from thomas31415/master
Fixed set mode for mining drill mk2 and mk3
2017-03-06 13:35:16 -05:00
ff6675ef28 Merge pull request #315 from cheapie/master
Only update the associated network(s) when placing/digging nodes
2017-03-06 00:35:44 -05:00
d3f40e0fd0 Only update the associated network(s) when placing/digging nodes 2017-03-05 04:09:23 -06:00
1765c31eaa Fixed set mode for mining drill mk2 and mk3 2017-03-05 09:01:50 +01:00
11610cd9cb Fixed set mode for mining drill mk2 and mk3 2017-03-04 19:44:39 +01:00
fd609d0f7b lower the cap on water mill to 1575 EU
2250 is just too much
2017-03-02 19:06:40 -05:00
1b0669d5eb Merge pull request #312 from cheapie/master
Crafting changes
2017-02-27 19:08:26 -05:00
dab5fa7105 Grind gravel into sand 2017-02-27 18:03:39 -06:00
5e19514c60 Add dirt recipe to centrifuge
4 dirt -> 2 clay lumps, 1 sand, 1 gravel
2017-02-27 17:58:43 -06:00
0139eab9a2 Rework dirt crafting
Dirt is now crafted from stone dust, leaves, water, and sand, instead of by grinding gravel. Stone dust can be obtained by grinding stone or sand.
2017-02-27 17:51:33 -06:00
1f49ef973d cap water mill output at max_output and 100% :P 2017-02-26 15:16:41 -05:00
cbe97434dc Add option to disable radiation protection 2017-02-25 20:55:15 -05:00
73afc40d9c Immortal entities support 2017-02-25 20:55:15 -05:00
b739ed6cb1 Made radiation configurable 2017-02-25 20:55:15 -05:00
51be33deea Restored weak shielding 2017-02-25 20:55:15 -05:00
1810f417d2 Radiation improved
Now it is applied to mobs too.
Moreover, it should now respect "radiation" armor group, or fall back to "fleshy" group to detect vulnerable things
2017-02-25 20:55:15 -05:00
4888581bee Make hydro generators sense the water flow volume around them
Water flow around a gen is shown more or less directly by the water's
param2, range 0 to 15, so four sides could total 60.  Cap the result to 45
so that three sides' worth of full flow (or four sides at reduced flow) still
registers as "100%", and raise the maximum outpu to 2250 EU.
2017-02-21 13:36:58 -05:00
8cab1a0aec don't allow standing water to power a gen,
and add support for default flowing river water
2017-02-21 13:21:23 -05:00
5dd6191175 Make mk3 drill in 3x3 mode drill nodes from top to bottom 2017-01-30 12:14:26 +02:00
06dec20326 Add longer-term radiation damage
Radiation now slowly damages you for a while after exposure,
with the effect's time and intensity proportional to the
amount of radiation received.  The radioactivity of some
items is reduced to account for the increased damage.
2017-01-28 17:51:14 -05:00
1da213a5e4 Split radiation from nuclear reactor code 2017-01-28 17:51:14 -05:00
26de2f7c88 Tweak radioactivity
This simplifies radioactivity by removing the 1000 and 0.25 multipliers.
It also increases the effectiveness of protection (I think it was too low
before -- most of the advantage of adding protective layers was just from
the increased distance).
2017-01-28 17:51:14 -05:00
8ccb6d97ec Switch nuclear reactor to a lead shield
The reactor originaly used a stainless steel shield only
because lead wasn't yet available.  Stainless steel shields
are automatically converted to lead shields for legacy reasons.
2017-01-28 17:51:14 -05:00
6b52c78963 Update chest definitions to current minetest_game definitions 2017-01-15 15:58:13 +01:00
5f1919d2bc Update has_locked_chest_privilege to current minetest_game function 2017-01-15 15:51:53 +01:00
Tim
d39797aad8 Handle CONTENT_IGNORE when checking windmill conditions.
Windmills always span more than one mapblock, so even with a switching station next to the generators, they will stop working if unloaded due to the windmill check failing to handle CONTENT_IGNORE of the frames at the foot of the windmill, unless a second switching station would be placed there.

The commit assumes, that a user has to load a block to modify it, and thus unloaded blocks to have the same windmill frame state as before.
This also makes technic_run for windmills a little faster by being able to skip some unnecessary node lookups and generally avoiding creation of 20 tables per windmill per step.
2016-11-17 11:59:48 -05:00
1475ee6e40 Add trace_node_ray_fat and use it for mining lasers
This function includes more nodes, so laser tunnels
aren't always only one node wide.
2016-11-17 11:48:19 -05:00
e501c4622b Replace trace_node_ray algorithm
This is an algorithm that I designed myself.  It fixes an
issue with the old code where it would be more eager to
move in some directions rather than others.  This bug
resulted in, eg, a lead block on a radiation source's
+x side protecting you when you were directly overhead.
2016-11-17 11:48:19 -05:00
cfd4cb7871 Update mining laser particle API usage 2016-11-17 11:48:19 -05:00
2b0a283556 Adjust mining laser start offset 2016-11-17 11:48:19 -05:00
63efc395cd fix node dupe exploit in frames
You can dupe nodes by placing them on a frame, because the on_rightclick wouldn't return the new itemstack.
2016-10-14 05:41:31 -03:00
Tim
7890ffe46b Fix drill drilling pointed_thing.above when some other mod declares a global variable above. 2016-10-09 17:46:44 +02:00
Tim
428b1b8709 Mitigate several forms of quarry-placement leading to item-transportation loops, that eventually cause server freezes.
As a nice side effect, items are not gonna be unnecessarily received by the quarry anymore, if another tube is available for transport.
2016-10-09 17:46:06 +02:00
99bebc8008 Update blast resistant concrete on_blast() to new TNT API
The destroyed item is now returned instead of being directly dropped, and the blast intensity value has changed.
2016-10-04 19:37:26 -04:00
03df68461a Power control added 2016-07-24 00:38:29 +03:00
e8ac23e111 Supply converter now has control panel 2016-07-24 00:34:20 +03:00
413d20d6c8 Updated Italian locale
Added missing translations
2016-05-18 15:22:20 +02:00
322615542e Fix item drop when digging mv furnace
Fixed crash when digging mv furnace
2016-05-12 23:59:16 +02:00
3db3a9cc32 Fix cable alias count 2016-04-01 19:58:37 -04:00
2258adb2a9 Replace nuclear reactor alarm sound 2016-03-30 22:53:29 +03:00
097d033585 Fix radiation damage 2016-03-20 22:38:30 -04:00
584cd82b58 Add support for new trees in minetest game 2016-03-20 13:30:18 -04:00
0c144cd75c Make blast-resistant concrete blast resistant 2016-03-20 00:08:50 -04:00
85a984982c Cleanup
Changes:
  * Make rayIter a global utility, and use it for radiation too.
  * prettynum -> pretty_num and cleanup.
  * Remove resolve_name/function_exists (unused).
  * Cleanup nuclear reactor code.
2016-03-20 00:02:33 -04:00
4a993c2de8 Use connected nodeboxes for concrete posts 2016-03-20 00:02:33 -04:00
83c6494166 Use connected nodeboxes for cables 2016-03-20 00:02:33 -04:00
f9a8593c87 Zinc is too rare!!! It is an issue!
Changed zinc parameters in first block block to match "lead noise" and "tin frequent". Please commit this! Zinc was a real problem to me untill i changed this file, now i can find about 10 zinc in 2 minutes!
2016-02-28 11:15:53 +03:00
c5127f4b1b Fix code style (useless or) 2015-11-28 08:31:27 +01:00
46f3f8ec7d Add vacuum cleaner tool (by Phvli) 2015-11-28 08:27:22 +01:00
e16a39b385 Revert "height_min/max --> y_min/max"
(due to misread of the code)

This reverts commit 798a885807.
2015-11-25 13:55:15 -05:00
8ef83e8f7e Fix corium greifing disabling not working. 2015-11-14 11:29:16 +01:00
798a885807 height_min/max --> y_min/max 2015-10-23 14:44:36 -04:00
71b13ab0e8 tile_images --> tiles 2015-10-23 14:15:48 -04:00
2d86ee64e3 Change tile_images to tiles 2015-10-16 13:55:57 -04:00
54b6d9976c CNC: re-add player inventory to formspec
Fix regression of commit

d732c8dfbd - "Add listring functionality"

by @est31 (me xD).
2015-09-12 08:04:07 +02:00
e7d06b33d1 fix missing radiation resistance for lead block 2015-09-12 01:34:57 -04:00
1b1780946e add facedir to tool workshop 2015-09-12 01:18:16 -04:00
28ed3b29a3 clarify license in README 2015-09-12 01:01:41 -04:00
ec3e3b348d copy rubber tree textures to technic_worldgen
should fix #222
2015-09-12 00:54:28 -04:00
cfd788358c Use moreblocks as an optional dependency. 2015-09-12 00:24:24 -04:00
e2ca7166f9 added rubber tree description
+added to group "leaves"
2015-07-28 16:20:00 +02:00
32d776293b Update my name in README.md 2015-07-24 11:46:34 +02:00
a529baba47 Machines should become inactive when output slots are full 2015-07-12 20:43:01 +02:00
a793747d92 Move coal furnaces to other/
They don't use power, move them to where they belong.
2015-06-18 04:16:47 +02:00
d732c8dfbd Add listring functionality
Add shift-click functionality
2015-06-18 04:09:27 +02:00
7cd848a050 default:mese_block is now default:mese
https://github.com/minetest-technic/technic/blob/master/technic/crafts.lua#L189
2015-06-17 17:10:03 -04:00
fcef0ef987 Make chests usable if pipeworks is not installed 2015-06-17 17:06:49 -04:00
ae7f49de38 Make chests usable without moreores (& add soft dependency) 2015-06-17 17:06:49 -04:00
84812d2307 Make technic_chests not (implicitly) depend on technic
(by moving two images that are used for chests only, from technic/textures
 to technic_chests/textures)
2015-06-17 17:06:49 -04:00
055ee23431 Readd myself 2015-06-06 10:39:47 -04:00
a4f7996b56 Readd myself
a large amount of the 16x16 textures were mine but when RealBad put them back in the information on them mustve been scattered to the winds, just fixing this.
2015-06-06 10:34:45 -04:00
24eca043d0 allow form backgrounds for chests to be textured separately 2015-05-03 15:13:45 -04:00
e393617fa1 Fix undefined global warning 2015-04-26 18:17:04 -04:00
35b0f068af Fix grinder name in recipe 2015-04-26 18:00:20 -04:00
4cf1e63adb put marble block into group marble=1 2015-04-18 17:12:06 -04:00
1615681e89 Fix autoloading for solar arrays
This autoloads the node above a solar array, so that its light value can be determined.
Previously, solar arrays in unloaded blocks would report an input of 0 to the switching station.
2015-03-23 03:41:03 +01:00
3f179e4c53 Make rubber leaves yield rubber leaves
Previously, you wouldn't get any leaves items from mining rubber tree leaves.
Leafdecay still doesn't drop the leaves, only the saplings, just like with normal trees.
2015-03-22 19:35:51 +01:00
6b800758fb Rename technic.cables and make it private
Give it a more descriptive name.
Previous use outside cables.lua isn't neccessary and gets removed.
2015-03-22 19:35:50 +01:00
Tim
137695ea67 allow activation/deactivation of frames/templates by config
have them deactivated by default due to a larger collection of associated issues
including but not limited to
* #170
* #216
* item duplication involving templates
* runaway machines
* traversal loop issues with huge machines leading to lag-outs
2015-03-16 18:58:41 -04:00
b00e942824 don't run the damage ABM if damage is disabled on the server. 2015-03-15 18:21:28 -04:00
cf75916ea7 Add spheres to the CNC machine
Note: this required renaming the base node name for the oblate spheroid
object, which previously had been named simply "sphere".  The result is
that all such nodes in an old world will change to actual spheres.

Since this includes a formspec change, machines will have to be dug and
re-placed to get the new program button to show up, and/or if the image
on the Oblate Spheroid button shows wrongly.
2015-03-12 00:02:23 -04:00
4874e29025 Wrench: fix restore of furnace (contents were not restored) 2015-03-11 18:10:16 -04:00
78bfa4f893 Wrench: when restoring picked_up_<item> to <item>, preserve rotation 2015-03-11 18:10:16 -04:00
ab6f2b2556 Make wrench usable independently of technic 2015-03-11 18:10:16 -04:00
b8c9028681 Tools don't wear in creative mode v2
- Removed cans (will add again per request)
- Added creative check to global namespace (checking only once as
requested by VanessaE)
2015-03-11 18:08:16 -04:00
19f74d11ba Change height_ to y_ in ore registrations 2015-03-11 18:08:16 -04:00
3624aabcf9 Update and rename wrench/locale to wrench/locale/tr.txt 2015-03-11 18:08:16 -04:00
e6f715062d Update and rename technic_worldgen/locale to technic_worldgen/locale/tr.txt 2015-03-11 18:08:16 -04:00
db35c9b54b add turkish locale 2015-03-11 18:08:16 -04:00
fe6965d89a Update and rename extranodes/locale to extranodes/locale/tr.txt 2015-03-11 18:08:16 -04:00
01fd5d6e6b Update and rename concrete/locale to concrete/locale/tr.txt 2015-03-11 18:08:15 -04:00
8b16fc1176 Add lead block, and lead & sulfur dusts 2015-03-08 13:32:59 +01:00
0113975160 Fix detection of if the machine should call pipeworks.after_place
The tube variable in these contexts always evaluates to a true value.
data.tube is the variable that indicates if pipeworks needs to be notified.
2015-03-07 21:44:42 -05:00
c8cbd261ee Drop upgrade items in the after_dig_node handler instead of can_dig
This fixes an item duplication bug triggered by using a screwdriver on an upgraded machine
2015-03-07 21:44:42 -05:00
Tim
c6464d3ebe label the switching station abm for profiling purposes
this allows the mtt profiler to profile this abm individually from other abms since t4im/mtt@48eff13
2015-02-28 00:47:15 +01:00
3eefa2f181 Add sulfur and lead, and make them generate 2015-02-22 12:42:46 +01:00
4b179821d3 Get rid of technic.format 2015-02-13 21:13:17 +01:00
Tim
7ed1aa9398 correct injector inventory handling by tubes 2015-02-11 03:15:34 +01:00
Tim
ce40d1cfb8 add group tubedevice_receiver to injector to fix the issue of it acting more like a tube than an inventory
it sent the items into all directions, when being injected into, instead of entering the injector as it used to
2015-02-08 12:27:10 +01:00
5ac93cccc9 simplify pipeworks tube detect
deMorgan's axiom, which I suck at using :P
2015-02-07 12:42:18 -05:00
cbfeb0192c fix crash placing chests re: tubes 2015-02-07 12:07:17 -05:00
bccefd6997 fix other machines, battery boxes, etc to work with tube routing. 2015-02-07 03:47:53 -05:00
d5db189cf4 fix chests connecting to tubes 2015-02-07 03:22:56 -05:00
Tim
48e02b8452 drop upgrade list items if dug (but protect other inventories) 2015-02-06 08:35:42 +01:00
Tim
72d541a607 add trunks: mod support to the chainsaw 2015-02-06 07:59:51 +01:00
Tim
a13e7b7ed1 add the option for publicly shared machines via an upgrade item "default:chest
the upgrade slots remain protected

this replaces the need for a few forks and also resolves #131 in the process, which is obsolete now
2015-02-06 07:54:29 +01:00
Tim
91e12c41fd fix chainsaw support for default:pinetree 2015-02-05 20:33:11 +01:00
Tim
96788677bb clean up upgrade handling a bit and only allow setting known upgrades 2015-02-05 17:27:28 +01:00
Tim
6ef3438832 limit the upgrade slot to one item per slot, as more are ignored anyway 2015-02-05 16:09:16 +01:00
Tim
41a10a86d5 reduce intllib code 2015-02-05 10:09:14 +01:00
Tim
c17732b16f localize modpath variable 2015-02-05 09:50:55 +01:00
Tim
49e82a604b supress undeclared variable access warnings in cases of intentional declaration checks 2015-02-05 09:47:37 +01:00
Tim
3fd53dfe95 add .mailmap 2015-02-05 09:41:38 +01:00
3bcd99f098 fix lighting glitch on bottom of "edge" (quarter-round) models 2015-02-05 01:08:09 -05:00
122e97ebd9 fix rotation of "edge" models 2015-02-05 00:58:42 -05:00
63fa7a856e fix broken lighting on CNC meshes, thanks to tip from acerspyro 2015-02-04 20:31:37 -05:00
4735055b94 Update chests formspec to not be deprecated 2015-02-03 11:14:26 +01:00
d452d16fa6 Make technic chests independent from unified inventory
Copy the textures made by RealBadAngel (under WTFPL) from unified inventory to technic to avoid minetest not finding them when unified inventory is not installed.
2015-02-03 07:43:58 +01:00
e08de57ec6 Update manual.md to respect new behaviour 2015-02-02 05:29:56 +01:00
9444eff7f7 Make switching station only react to nodes from below 2015-02-02 05:29:44 +01:00
18265de3b3 Fix bug for switching stations displaying same input and output 2015-01-31 10:42:55 +01:00
3dc01a6720 Formatting for supply converter too 2015-01-31 10:42:55 +01:00
d9bf9830b0 Better number formating
Is it 120000 or 1200000?
2015-01-31 01:29:16 -05:00
0c3f55e0c9 fix cobble and gravel grinder recipes 2015-01-30 14:29:50 -05:00
Tim
6dd7ffc455 move from recipe defusion to recipe deactivation to avoid confusion 2015-01-30 20:15:15 +01:00
Tim
a0cf9eb8f3 replace overlooked latex->rubber furnace recipe with glue as a form of "rubber cement" 2015-01-30 17:50:06 +01:00
Tim
b9173be3b8 remove unnecessary definition fields 2015-01-30 17:47:04 +01:00
Tim
91fceece18 tune latex->rubber alloy recipe based on wikipedia data pointed out by @est31 2015-01-30 17:41:05 +01:00
5a395928fa add textures for grindings/sawdust 2015-01-30 00:17:28 -05:00
Tim
f330d58354 redfine latex->rubber path via alloy furnace
latex is being refined to rubber by drying and adding carbon pigments to strengthen the material
(which also turns it black)
it should not yield more rubber than its latex input, but it may be processed faster than ores
2015-01-30 05:16:49 +01:00
Tim
56e96b2593 add sawdust and tree/wood grindings with arcacia tree for dye and provide a better alternative rubbertree->latex path that yields the same as the tree tap, but requires more machine work
yet without textures
2015-01-30 05:16:41 +01:00
Tim
80f79f5e1e remove _sidways moretree trunks from chainsaw, these would be abm-converted before anyone could saw them anyway 2015-01-30 05:09:21 +01:00
Tim
a8c097bcd9 tweak sandstone/sand recipes to a more efficent compressing 2 sand -> sandstone and grinding sandstone -> 2 sand ratio; make sure the default recipes are defused 2015-01-30 05:09:21 +01:00
Tim
3cc568ddbd defuse by fake_fire added recipes, make people use the grinder for those 2015-01-30 05:09:21 +01:00
Tim
9d3f7304fb add a sandstone compression recipe back in place of the default recipe, without leading to an infinite sand/sandstone generation which lead to its removal in c0a1739 in the first place 2015-01-30 05:09:21 +01:00
Tim
e4c34c9c32 allow transformer and chainsaw crafts even if required mesecon modules are not loaded 2015-01-30 05:09:21 +01:00
Tim
1d81e6d4d1 register additional technic materials with the circular saw 2015-01-30 05:09:21 +01:00
Tim
581afee261 update extranodes to use the new api of moreblocks/stairsplus 2015-01-30 05:09:21 +01:00
Tim
9087abcde0 add centrifuge recipe for wheat 2015-01-30 05:09:21 +01:00
Tim
00f61dfb81 rewrite extractor dye recipes, adding a few dyes and making it work better with the dye mod
also preventing any issues if it is being run in a game without it
2015-01-30 05:09:20 +01:00
Tim
a8b711a7f4 allow grinding wheatseeds to flour, closes #173 2015-01-30 05:09:20 +01:00
Tim
fe4372649f reuse the new screwdriver code of minetest/minetest_game in adapted form for the sonic screwdriver 2015-01-29 18:38:23 -05:00
Tim
3252da05d1 use the timers, that are allready running instead of allocating a new one every tick 2015-01-27 19:02:33 +01:00
f250e1632f Give quarries a better inventory icon
Current inventory icon is indistinguishable from carbon steel block. The side with the pick was hidden. This commit moves that part to the front.
2015-01-24 21:23:26 +01:00
86dd5852aa Add cache to quarry
Adds a cache to the quarry in order to reduce load and send larger stacks through pipes instead of just single items. Coin tossing ensures the cache gets purged around every 200 seconds. The interval isn't fixed in order to prevent material spikes from multiple quarries which got loaded simultaneously. When the cache is full, or the quarry finished, it is purged too.
2015-01-24 21:22:49 +01:00
c38da0945c Optimize quarry_run
Don't load the whole digging area when only a small piece is relevant.
Also, move the (time expensive) check whether the air above a block is free to the last position, which spares unneccessary checks when multiple quarries are placed together, or a quarry has to loop over air for another reason.
2015-01-24 19:40:02 +01:00
ec73a8508f add custom collision and selection box handling to CNC machine
also clean up formatting of surrounding code
2015-01-19 13:37:46 -05:00
Tim
7e92fe0a46 use an alternative and cleaner way to overwrite the pipeworks tube-recipes and default bronze 2015-01-18 20:34:15 +01:00
9e1c5740d3 Fix support for acacia trees
Just realized I had the wrong item string >.<
2015-01-16 20:08:25 -05:00
d6b0deb989 fix cnc stick formspec img
(missed the border)
2015-01-16 19:16:39 -05:00
1a7a17f3d7 new high-resolution imagery for CNC formspec
to go with the new models.
2015-01-16 19:12:02 -05:00
3726bd9bd2 add the models too 2015-01-16 17:19:11 -05:00
80cb6a495a Use mesh nodes for all of the more complex CNC machined items 2015-01-16 16:57:34 -05:00
Tim
0114feaf04 Add more nodes to the chainsaw 2015-01-12 17:51:55 -05:00
2e04374de8 Add gloopores' Kalite dust as a more effecient fuel than lumps 2015-01-12 17:51:55 -05:00
bc0ac581aa prevent crash if get_recipe_index() is passed a nil or apparent garbage instead
of a table
2015-01-12 17:43:56 -05:00
4ac36e9d27 Fix infinite energy with supply converter 2014-12-30 12:10:36 +01:00
5382a88aef Fix some global errors 2014-12-15 17:47:07 -05:00
a413904ecd minetest.env:* --> minetest.* 2014-11-30 12:45:42 -05:00
dd30838245 Add more nodes to chainsaw 2014-11-30 08:28:57 +01:00
8da4d057b0 update to latest mesecons API
requires mesecons commit 5be179bf110b44bdc06df6dbfde4e61487cf0635 or later.
2014-11-22 13:58:38 -05:00
f13570b59b Fix support for tiles string shortcut 2014-11-13 12:57:26 -05:00
30a37a490f Make the forcefield replace buildable_to nodes and make it faster (about x20) 2014-11-13 12:28:04 -05:00
aef07eb604 Manual section on radioactivity
Manual section on radioactivity
2014-11-06 09:03:01 -05:00
f205e5f404 Fix anonymous digging of non-empty machine
The quarry was causing crashes when it reached a machine that was
undiggable due to containing items.
2014-11-06 08:33:14 -05:00
7c6c3b9679 Remove extra registration of LV transformer 2014-09-24 20:35:25 -04:00
42d0081367 Replace mining laser ray tracer with a simpler iterable one 2014-09-24 20:32:36 -04:00
4d1f9753e3 update mining lasers 2014-09-16 15:23:46 -04:00
6d90ebb94e Make generators stop supplying EUs when there is a non-fuel item in the fuel slot 2014-09-16 15:21:14 -04:00
0defb2e66d Fix broken concrete posts. 2014-08-29 01:26:25 +02:00
0de4fec07c Fix second description of radioactive group value 2014-08-28 15:30:15 +02:00
fd527c2d98 Manual section on nuclear generator 2014-08-28 15:21:50 +02:00
23423ab79b More manual on power generation
Sections on solar and wind.  Some rewording of the section on fuel-fired
generators.
2014-08-28 15:20:26 +02:00
1d46d71b25 Manual sections on some generators 2014-08-28 15:18:12 +02:00
45919b871a Make forcefield properly undiggable 2014-08-28 15:14:05 +02:00
706e880f05 Manual sections on miscellaneous powered machines 2014-08-28 15:13:04 +02:00
7c85726e9a Fix a stray British spelling in manual 2014-08-28 15:05:26 +02:00
8cec4180af Manual section on processing machines 2014-08-28 15:02:02 +02:00
04e911f94b Start of manual chapter on powered machines 2014-08-28 15:01:13 +02:00
3b1abaaa56 Manual section on concrete 2014-08-28 14:37:36 +02:00
ec069aa43e Change chainsaw cutting algorithm back to old one
The new algorithm caused horizontal sections of trees to be left, with the
sections above and below them removed.
2014-08-22 20:57:30 -04:00
16302cffce Fix chainsaw placing drops and playing sounds at tops of trees 2014-08-22 20:01:15 -04:00
78646b2d89 Make tree tap respect item_drop 2014-08-22 14:20:13 +01:00
0cf4133b97 Make wrench available in creative mode only
The wrench is far too powerful to be available to survival-mode players
via a cheap recipe.
2014-08-22 01:07:38 +01:00
7ab3f9bed2 Update wrench's metadata for technic machines
The changes that this covers are that the alloy furnaces now have one
"src" inventory instead of a "src" and "src2"; that the tool workshop
is now MV; and the existence of MV compressor, extractor, and centrifuge.
2014-08-22 01:01:44 +01:00
2912e2da78 Rebalance radiation shielding
Squeeze the range of material shielding values.  The strongest shielding
materials get weaker, and weaker shielding materials, especially low-end
ones such as dirt, get stronger.  The radioactivity of the active
reactor core is increased so that the standard shielding is (still)
only narrowly sufficient.
2014-08-20 20:09:41 +01:00
7a9d2ffe5f Finer gradations of radioactivity
Make the "radioactive" group value be the safe distance in millimeters
rather than meters, to allow for intermediate values.  Use such
intermediate values for the uranium blocks, using the existing formula
with this finer quantisation.  All other radioactive nodes retain their
existing radioactivity exactly.
2014-08-20 19:14:03 +01:00
7d610b7c80 Tube capability for tool workshop
Tool workshop can now accept tools to repair via tube.  It has upgrade
slots.  Battery upgrade reduces its power consumption.  Tube upgrade
makes it eject fully-repaired (or unrepairable) items via tube.
2014-08-18 17:09:37 +01:00
814646b542 Smoother link of processing cycles to ABM cycles
Make the generic processing machine code willing to complete more than
one processing cycle in one ABM cycle, and more generally to carry
over leftover processing effort after completing a processing cycle.
The src_time meta item now represents accumulated processing effort
(time multiplied by speed) in a scaled form (to retain fractions),
rather than just time in integral seconds.  This affects the MV furnace,
with speed 4 and most recipe times being 3 s, and will be essential for
faster furnaces.
2014-08-18 15:14:15 +01:00
d0efa15b98 In quarry, skip past undiggable nodes
The quarry used to get stuck when it encountered an undiggable node.
Change it to skip past that node, digging whatever later stuff it can.
Necessarily, the current digging position becomes semantically-significant
state: it is no longer sufficient to search the quarry cuboid from the top
on each iteration.  The current digging height is reported in the quarry's
interaction form, and can be reset to the top using a button on the form.

Where there is a non-air node within the quarry directly above the
next node to dig, it blocks the quarry's access to that node, even if
everything involved is diggable.  Thus an undiggable node casts a shadow
of undug nodes below it.  Resolving undiggability of a node is a major
reason to use the restart button.
2014-08-18 15:14:15 +01:00
390ade6e54 Change oregen to a non-uniform distribution. 2014-08-17 17:08:11 +02:00
d0001a20c9 Fix visible cable connection for irregular items
The switching station and supply converter only semantically connect to
cables in particular directions.  Make them visually connect only in
the matching directions.  This is done by special-casing in the cable
update logic.  If more irregular items arise in the future, or the
existing items start to need facedir logic, this should be generalised
into something like the connect_sides system for pneumatic tubes.
2014-08-17 13:43:39 +01:00
35b10adb40 Fix items sending 2014-08-16 13:42:17 +02:00
849526cd76 Fix forcefield power demand when disabled 2014-08-15 12:25:47 +01:00
830de45936 Option for forcefield to be cubical 2014-08-15 12:25:46 +01:00
6cc471e986 Simplify music player interface
Having a track selected now implies playing it, rather than
playing/stopped being a hidden state separate from track selection.
2014-08-15 12:25:46 +01:00
1d0687556a Fix music player's sound management
If an operating music player was disconnected from the electrical network
or destroyed, it used to leave the music playing forever.  There was
also a glitch upon starting playing, as the music was started by the
form handler but then stopped when the run function realised it wasn't
receiving any power, because it hadn't demanded any yet.
2014-08-15 12:25:46 +01:00
049129d9b8 Handle both pipeworks APIs
The new API function is now renamed to pipeworks.tube_inject_item(),
so use it under that name.  If it is not available, synthesise the new
API in terms of the old one.
2014-08-15 13:23:41 +02:00
772c21cb04 don't put anchor in creative inv 2014-08-14 21:56:05 -04:00
baf7f61665 Compatibility with latest pipeworks 2014-08-14 21:29:56 +02:00
3b16a2858f Revise rules for regenerating latex
To ensure that only rubber tree trunk nodes that are part of trees
regenerate, rather than those that are used as building blocks, check
that they are sufficiently close to rubber tree leaves.  This replaces the
older rule that naturally-grown trunks regenerate (regardless of leaves)
and manually-placed trunks don't (even though manually building a tree
otherwise works).  The detection of manually-placed trunks was in any
case broken for users of moretrees, because that mod fails to set the
flag signalling manual placement.

Incidentally also fix a bug that caused rubber tree branches (horizontal
trunk nodes) to turn vertical when regenerating latex.  Rather than set
the complete node structure, only switch the type name, as does the tree
tap when emptying the node.
2014-08-13 23:13:52 +01:00
b001a67979 Administrative world anchor 2014-08-13 19:07:53 +01:00
38e85e9775 Manual section on uranium enrichment 2014-08-13 02:45:44 +01:00
df7bf8c713 Manual sectioning
Expand list of sections yet to be written.  Arrange sections both written
and unwritten into a two-level structure, with a bit of consequential
reordering.
2014-08-13 00:25:15 +01:00
7112e742f4 More manual
Added section on chests.  Fixed another stray British spelling.
Backslashed literal underscores to avoid them being interpreted as
emphasis markup.
2014-08-11 13:04:53 +01:00
5692c29a45 More manual
Sections on rubber and electrical power.
2014-08-09 13:59:46 +01:00
eed803349c More manual
Added sections on the technic-specific kinds of item processing, and on
generic metal mechanics, and the specific trickery around iron (merging
in notes_on_iron).
2014-08-08 23:22:36 +01:00
ddb522d4cc Fix stray British spellings in manual 2014-08-08 19:36:43 +01:00
e3b44be6ec Change "altitude" to "elevation" in manual
Vanessa finds "altitude" to carry too much of an aviation connotation.
Zefram finds "elevation" to carry insufficient connotation of being
relative to sea level, so also adds a clarifying note.  Beware of changing
this terminology without negotiation, as it aroused surprisingly strong
opinions.
2014-08-08 17:40:28 +01:00
488070c1ee Start on user manual 2014-08-08 16:41:31 +01:00
7cfb3874a3 Evenly distribute charge across multiple batteries 2014-08-06 12:08:48 -05:00
ab567e21ca Remove non-functional tetris machine 2014-08-04 13:43:57 -04:00
4996d1824c Make nuclear reactor core harder to break
With breaking an active reactor core now causing instant meltdown, having
it breakable by hand is too hazardous.  Change it to match steel block,
which constitutes the main part of the rest of the reactor structure.
2014-08-04 12:54:47 -04:00
a2d1fefe14 Realistic range of radioactivity of uranium blocks
Fully-depleted uranium doesn't lack noticeable radioactivity.  The
radioactivity of enriched uranium is dominated by the U-234 fraction,
not U-235.
2014-08-04 17:03:56 +01:00
fc87eca4cd Fix technic_run declaration for hydro generator 2014-08-04 14:58:38 +01:00
8275091347 Improve injector interface
Make the injector's mode button lag-resistant.  Display the mode on
the button, as is done with other machines' toggle buttons.  Describe
the modes using the same words that are now used to distinguish the
corresponding pipeworks objects.  Expand name to "self-contained
injector", now that the pipeworks objects are also called "injector".
Show injector item image along with the item name at the head of the form.
2014-08-01 18:25:20 +01:00
daa6135211 Update alloying craft guide to match machine
The alloy furnaces have been changed to lay out the input slots
horizontally.  The craft guide should match that, for mnemonic value.
2014-08-01 17:56:32 +01:00
beb480bec2 Redescribe alloying in craft guide
Change "Alloy cooking" to "Alloying", for consistency with the
descriptions of other recipe types.
2014-08-01 17:50:40 +01:00
0003ec6a79 Make carbon steel alloying quicker
Taking the same time per alloying cycle as other alloys meant that carbon
steel was being produced painfully slowly, becuase it processes much less
material per cycle than other alloys.  This change halves the cycle time,
which leaves it still processing less material per second than other
alloying processes, but by a less drastic margin.
2014-08-01 17:40:35 +01:00
2a7ee141eb Fix behaviour on decabling a forcefield emitter 2014-08-01 17:30:21 +01:00
88bdac62e3 Merge remote-tracking branch 'zefram/zefram/centrifuge' 2014-07-30 15:36:27 -04:00
12d0c6522b Correct breakability of sandstone CNC nodes
default:sandstone has cracky=3, but the CNC nodes had cracky=2.
2014-07-30 20:28:30 +01:00
0dfac3f484 Make granite harder than regular stone
In real life granite is renowned for its hardness.
2014-07-30 20:25:35 +01:00
60bc80692b Remove a noisy debugging print 2014-07-28 13:29:39 +01:00
b0faa70873 Uranium enrichment via centrifuge
Replacing the extractor-based system, uranium to be used as reactor fuel
must now be enriched in stages using the centrifuge.  Uranium metal can
exist at 36 levels of fissile content, from 0.0% to 3.5% in steps of 0.1%.
One round of centrifuging splits two dust of a particular grade in to one
dust each of the two neighbouring grades.  Uranium of each grade can exist
as dust, ingot, and block, with all the regular metal processes to convert
between them.  Uranium from ore exists in lump form, and is 0.7% fissle.
The blocks are radioactive to a degree dependent on fissile content.
Thus the chemical refinement and processing of uranium now follows the
standard pattern for metals, and is orthogonal to isotopic enrichment.
Each form of uranium (dust, ingot, block) intentionally looks identical
regardless of fissile grade.

If technic_worldgen is used alone, it defines only one grade of uranium
(as before), but defines it in the regular metal pattern, with lump, ingot
produced by cooking lump, and block crafted from ingots.  It identifies
the metal only as "uranium".  The multiple grades of uranium are defined
by the technic mod, which identifies each grade as "N.N%-fissile
uranium".  The single grade that was registered by technic_worldgen
is redefined to be described specifically as "0.7%-fissile uranium".
For the redefinition to work, technic_worldgen must load before technic,
so technic now declares a dependency on technic_worldgen.

Each fuel rod is made from five 3.5%-fissile ingots, each of which in
turn requires one to start with five 0.7%-fissile dust, so each fuel rod
is now derived from 12.5 uranium lumps (or 25 if the lumps were first
cooked rather than being ground).  This replaces the 20 lumps required
by the former recipes.  After setting up and priming the centrifuge
cascade, enriching a full set of fuel for the reactor (six fuel rods)
takes 14700 centrifuge operations.  It's intended to be a practical
necessity to automate the centrifuge.  In the absence of EU upgrades
for the centrifuges, these operations consume 5.88e8 EU, about 0.97%
of the 6.048e10 EU that the fuel set will produce in the reactor.
The intent is that, in this respect as in others, operating a reactor
should carry a very high up-front cost, but ultimately be very profitable.
2014-07-28 13:18:51 +01:00
d60e3fe939 Reduce dependencies of technic_chests
technic_chests was depending on the technic mod, for the top-level
"technic" table and the technic.swap_node function.  Resolve that by
sharing the top-level table and inlining the one use of the function.
It was also depending on technic_worldgen, for the definitions of
cast iron and wrought iron.  Make the use of cast iron conditional on
technic_worldgen, falling back to default "steel".  Change the use of
wrought iron to directly use default "steel", to which it is aliased
anyway.
2014-07-26 19:45:31 +01:00
9f0b41fe71 Make technic_worldgen loadable before technic
There was a small amount of dependency of technic_worldgen on the
technic mod, for configuration loading and the top-level "technic" table.
Resolve that by sharing the configuration and top-level table between the
two mods.  This means that technic_worldgen can be loaded before technic,
permitting other mods to depend on it without depending on technic.
2014-07-26 19:20:45 +01:00
dd65a68ce9 Add centrifuge
The centrifuge, currently only existing in an MV variety, is a machine
that separates a mixed substance into its constituents.  Currently the
main use is to reverse alloying of metals.  The alloy separation recipes
intentionally only operate on the dust form of metals, making this less
convenient than the original alloying.  It also only recovers metal
constituents, not the carbon that went into cast iron or carbon steel.

This change incidentally generalises the technic recipe and
machine infrastructure to handle recipes with multiple outputs.
As unified_inventory's craft guide can't yet handle that, these recipes
are not registered there.
2014-07-26 18:01:05 +01:00
84cf6504c5 Make outer layer of reactor structure optional
As the layers of reactor structure now have a practical purpose,
in attenuating the modelled radiation from the core, it is no longer
necessary to make so much of it mandatory in order to motivate players
to build it.
2014-07-25 17:27:55 +01:00
d59055dd2b Audible siren to warn of reactor meltdown
The siren sounds a "danger" tone continuously while it is active and
damaged, such that meltdown is imminent.  It sounds a one-off "clear"
tone if it has been sounding "danger" and the danger has passed, either
because the structure is repaired or because the reactor has become idle.
2014-07-25 15:38:40 +01:00
67b90f3ad1 Grace period before reactor meltdown
The meltdown check now doesn't trigger meltdown immediately on reactor
structure being compromised.  Instead, there's a grace period of up to
100 s, during which the reactor can be repaired.  The check doesn't just
look at whether the structure is damaged at all: it looks at how damaged
it is, counting the number of faulty nodes.  The amount of damage is
integrated over time, and the grace period is actually 100 node-seconds,
so greater damage causes meltdown more quickly.  If the active core is
dug then it melts down immediately, preventing the tactic of digging
the core to avert meltdown.

Incidentally move the meltdown check into its own ABM, from the
technic_run callback, so that it applies even when the reactor is not
connected to a switching station.
2014-07-25 14:24:25 +01:00
ec008d7045 Material-dependent radiation shielding
Radiation is attenuated exponentially by passing through shielding
material.  Radiation resistance values are assigned to all bulk-material
nodes, and the radiation damage ABM traces the path of each radiation ray
to count up the shielding.  The relative radiation resistance values are
essentially real, but the effectiveness of all shielding is scaled down
by a factor of about 70 for game purposes.  Strength of the existing
radiation sources is increased by varying amounts to compensate for
shielding.  Uranium block and ore, both usable as shielding, are made
slightly radioactive, the latter only very slightly.
2014-07-25 03:42:21 +01:00
17c5b66524 Inverse square law for radiation damage 2014-07-24 17:38:53 +01:00
e64fdbf03b Fix celeron55 credit 2014-07-23 18:47:04 -04:00
e11f0f8817 Tweak corium light settings
Flowing corium appeared too dark.
2014-07-23 18:45:50 -04:00
c5e9480d99 Config setting to nerf corium
For use on servers that have a mainly creative purpose, the setting
enable_corium_griefing=false will prevent corium from flowing far or
unpredictably and from destroying nodes other than water.  All reactor
meltdowns will stay contained.
2014-07-23 17:24:52 -04:00
366fc3bc65 Better reactor meltdown
Reactor `explosion' now replaces the reactor core with a corium source
node.  Corium is a new liquid, which flows a bit like lava, but has
the additional feature of destroying nodes to which it is adjacent.
It also randomly turns into a solid form, chernobylite, which makes an
attractive building block.  It thus gradually melts its way through the
reactor shielding layers; a meltdown gets worse over time if not cleaned
up promptly.

The mechanism for an active reactor core to damage nearby players is
generalised into a "radioactive" node group.  Corium and chernobylite
are radioactive, to varying degrees.  Players receive a varying amount of
damage from a radioactive node, depending on proximity.  Staying outside
a reactor cube is sufficient to be safe from the active core, but not
sufficient to be safe from a melted core.
2014-07-23 20:21:59 +01:00
62e04b9c0d Improved can usage
Make the use of cans more like the digging and placement of ordinary
nodes, and specifically make it much closer to the use of buckets.
The main change is that left-click with a can is now only used to take
liquid; placing liquid is now done with a right-click.  This makes the use
of cans a lot less error-prone, compared to the old scheme of determining
the operation based on the type of node pointed to.  Other changes are
that liquid placement is now permitted to replace any buildable_to node,
and the cans obey node protection.
2014-07-23 20:21:59 +01:00
6771ad9d33 Genericise can logic
Factor out the logic common to water and lava cans.  Provide it in the
form of a technic.register_can() function, which can be called by other
mods to register cans for other liquids.
2014-07-23 20:21:59 +01:00
cca72f43f1 Tweak mesecon control of forcefield
Drop support for negative mesecon control.  This requires users of
negative mesecon control to invert their mesecon signal externally.

Comment on rationale for the way toggle buttons in formspec are managed.
2014-07-23 16:49:08 +01:00
6a4cb16392 Fix mesecon control of forcefield
The code formerly attempted to make the forcefield emitter controlled
both manually and by (inverted) mesecon signal, but the two interfered
with each other.  In particular, a newly-placed emitted would be
informed that it was getting no mesecon signal, and would therefore
enable itself.  Fix this by adding explicit modes for how the emitter
will respond to mesecon signals: ignore them, obey them positively,
or obey them negatively.

The manual control could have been incorporated into this mode setting
by having two "ignore mesecon" modes: always-enabled and always-disabled.
But it seems more useful to have a separate manual master switch, so that
the emitter can be manually disabled without losing the mesecon mode.
So it is now implemented that way.
2014-07-23 16:49:08 +01:00
1bf52c2d5a Better chest color button layout
Where possible (which it currently is for the gold chest), don't break
the centering of the player inventory in the chest formspec because
of the color buttons.  Where the color buttons don't fit next to a
perfectly centered player inventory (which doesn't currently occur for
any technic chest), move the player inventory only as much as necessary
to accommodate the color buttons.
2014-07-23 16:49:08 +01:00
1d7cb74053 Bring wooden chest fully into the chest system
Re-register most aspects of default:chest and default:chest_locked,
using the technic chests code, so that the wooden chests fit properly
into the sequence of chest types.  This mainly affects the formspec,
which now uses the style of the other chests, rather than the bare style
used by the default mod.
2014-07-23 16:49:07 +01:00
2d9e06c479 actually make the reactor core melt down when it should
(turns into a lava source, boils away the surrounding water)
2014-07-23 11:08:11 -04:00
29c7ff5228 don't attempt to force-load blocks if they're already loaded. 2014-07-23 10:00:13 -04:00
ad0c310b6b Remove dependency on moreores that was accidentally left in place 2014-07-21 13:21:13 -04:00
14b30bfd0d Clean up constructor 2014-07-21 01:52:13 -04:00
7d5edcf23e Remove swap_node compatability code 2014-07-21 00:40:53 -04:00
87fc21443c Add hack for uninitialized players in flashlight 2014-07-21 00:14:55 -04:00
37c06a9110 log_mod -> log_mods and get setting as boolean 2014-07-21 00:13:45 -04:00
22a4bcf80d Remove mods that aren't strictly required from depends.txt 2014-07-20 23:49:38 -04:00
dd468c3aaa Merge pull request #152 from goblin/coal_alloy_return_bucket
alloy furnaces and generators should not eat fuel buckets
2014-07-18 20:19:15 -04:00
6ec12b51cb also return buckets with generators
... and in the `smelt_item` function, even though it seems unused
2014-07-19 00:18:44 +01:00
9290e6f00d coal alloy furnace to return the buckets 2014-07-18 17:08:05 +01:00
69487e530b Fix drill recipe
It was attempting to get the copper ingot from the wrong mod.
2014-07-14 15:19:02 +02:00
efd5ff644c Fix supply converter again 2014-07-14 11:16:37 +02:00
7065ba9155 Fix problem with supply converter producing energy 2014-07-13 14:15:10 +02:00
1af6313c69 Fix crash with supply converter 2014-07-12 18:22:52 +02:00
1c617f2c5e Make unconnected generators burn the fuel they still have. 2014-07-12 09:50:50 +02:00
563a4c071d Make switching station run all machines it is connected to, including those in unloaded blocks. 2014-07-11 11:00:46 +02:00
871ded6e6a Increase prospector's charge capacity
The low capacity of the prospector turned out to be annoying, while the
other limitations do not substantially detract from fun.  Also adjust
recipe to include a blue energy crystal, to explain the source of the
charge capacity.
2014-07-10 08:56:48 +02:00
83e9cab3ad Better ingot textures 2014-07-09 19:03:22 +02:00
78128fd49a Tweak energy crystal recipes
Use silver instead of gold in the recipe for the red energy crystal,
and mithril instead of gold in the recipe for the blue energy crystal.
This provides more appreciable steps in the expense of the upgrades,
which were too similar, and in particular makes the blue energy crystal
less ridiculously cheap.
2014-07-09 09:17:44 +02:00
5e4a87b925 Rework some recipes to use more varied ingredients 2014-07-09 09:17:44 +02:00
5e7c47a619 Exclude technic:nothing from creative inventory 2014-07-09 09:17:44 +02:00
5ec2d10dbc Vary cable insulation type with tier
LV cables are now paper-insulated, rather than uninsulated (which made
no sense).  MV cables are rubber-insulated as before.  HV cables are now
plastic-insulated (which they already visually appeared to be).  MV and
HV cables are still crafted by adding insulation onto lower-tier cable,
rather than by insulating raw copper; this matches the way machines are
upgraded between tiers rather than crafted afresh.
2014-07-09 09:17:44 +02:00
f7819b4cb8 Remove duplicate cable textures
Some of the technicx32 cable textures were just duplicates of the
standard-resolution textures.
2014-07-09 09:17:44 +02:00
3f717cbb9e Fine gold and silver wire items
Not used in any recipes yet.
2014-07-09 09:17:44 +02:00
4958a77e21 Tweak supply converter recipe
The casing is now in the center of the grid, as it is for all other
machines.
2014-07-09 09:17:44 +02:00
68ea0acbd0 Consistently use cable in electric machine recipes
All electric machine recipes now include cable of the appropriate tier
as the bottom-middle ingredient, immediately below the casing ingredient.
Many LV machines were using a copper ingot in that location.
2014-07-09 09:17:43 +02:00
e8a5a6652d Use machine casing in most machine recipes 2014-07-09 09:17:43 +02:00
430b310eb4 Machine casing item
The casing is intended to be an ingredient in craft recipes for machines.
It isn't actually used in any recipes yet.  Although mainly a craft
item, it is defined as a node type, mainly to get an appropriately cubic
inventory image.  It is incidentally possible to place it as a node:
this makes some sense, although the empty machine casing isn't actually
useful as a node.
2014-07-09 09:17:43 +02:00
636b0f20df Handheld prospecting tool
The new tool will say whether a target block type is present in a
specified region, to allow for more targeted digging.  It is deliberately
quite weak, with several limitations: only stores enough charge for a
small number of shots; target can only be set by pointing at an example
node; range is limited; accuracy is less than 100%.  Some of these
limitations should probably be ameliorated, but not entirely eliminated,
in the future when we have a better idea of game balance.

The inventory image is only a placeholder.
2014-07-07 15:15:05 +02:00
611c7760eb Fix fuel-fired alloy furnace
Commit ee0765804c broke the fuel-fired alloy
furnace, by removing the definition of its formspec that it requires to
set up the form upon construction.
2014-07-07 15:15:05 +02:00
e5cc3359e0 Fix craft guide for alloy cooking et al
A typo in commit d55ecc39f9 made recipes
for alloy cooking, compressing, and all other craft types sharing that
machine code, to be shown with three ingredient slots instead of the
correct one or two.
2014-07-07 15:15:05 +02:00
ad157d1b8f Fix brass alloying recipe
Commit d55ecc39f9 introduced a bogus
reference to "technic:copper_ingot".
2014-07-07 15:15:05 +02:00
263 changed files with 12823 additions and 3800 deletions

1
.gitignore vendored
View File

@ -48,7 +48,6 @@ local.properties
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc

4
.mailmap Normal file
View File

@ -0,0 +1,4 @@
RealBadAngel <maciej.kasatkin@o2.pl> <mk@realbadangel.pl>
Vanessa Ezekowitz <vanessaezekowitz@gmail.com>
Vanessa Ezekowitz <vanessaezekowitz@gmail.com> <vanessa@rainbird.(none)>
kaeza <kaeza@users.sf.net> Diego Martínez <kaeza@users.sf.net>

View File

@ -4,7 +4,7 @@ Technic
Credits for contributing to the project (in alphabetical order):
* kpoppel
* Nekogloop
* Nore/Novatux
* Nore/Ekdohibs
* ShadowNinja
* VanessaE
* And many others...
@ -18,5 +18,6 @@ FAQ
License
-------
See mod folders for their licences
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.

View File

@ -1,22 +1,20 @@
--Minetest 0.4.7 mod: concrete
--(c) 2013 by RealBadAngel <mk@realbadangel.pl>
local technic = technic or {}
local technic = rawget(_G, "technic") or {}
technic.concrete_posts = {}
-- Boilerplate to support localized strings if intllib mod is installed.
local S
if intllib then
S = intllib.Getter()
else
S = function(s) return s end
end
local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
minetest.register_alias("technic:concrete_post", "technic:concrete_post0")
minetest.register_alias("technic:concrete_post32", "technic:concrete_post12")
minetest.register_alias("technic:concrete_post33", "technic:concrete_post3")
minetest.register_alias("technic:concrete_post34", "technic:concrete_post28")
minetest.register_alias("technic:concrete_post35", "technic:concrete_post19")
for i = 0, 31 do
minetest.register_alias("technic:concrete_post"..i,
"technic:concrete_post")
end
for i = 32, 63 do
minetest.register_alias("technic:concrete_post"..i,
"technic:concrete_post_with_platform")
end
local steel_ingot
if minetest.get_modpath("technic_worldgen") then
@ -46,17 +44,17 @@ minetest.register_craft({
minetest.register_craft({
output = 'technic:concrete_post_platform 6',
recipe = {
{'technic:concrete','technic:concrete_post0','technic:concrete'},
{'technic:concrete','technic:concrete_post','technic:concrete'},
}
})
minetest.register_craft({
output = 'technic:concrete_post0 12',
output = 'technic:concrete_post 12',
recipe = {
{'default:stone','technic:rebar','default:stone'},
{'default:stone','technic:rebar','default:stone'},
{'default:stone','technic:rebar','default:stone'},
}
}
})
minetest.register_craft({
@ -68,13 +66,6 @@ minetest.register_craft({
}
})
local box_platform = {-0.5, 0.3, -0.5, 0.5, 0.5, 0.5}
local box_center = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}
local box_x1 = {0, -0.3, -0.1, 0.5, 0.3, 0.1}
local box_z1 = {-0.1, -0.3, 0, 0.1, 0.3, 0.5}
local box_x2 = {0, -0.3, -0.1, -0.5, 0.3, 0.1}
local box_z2 = {-0.1, -0.3, 0, 0.1, 0.3, -0.5}
minetest.register_craftitem(":technic:rebar", {
description = S("Rebar"),
inventory_image = "technic_rebar.png",
@ -82,33 +73,35 @@ minetest.register_craftitem(":technic:rebar", {
minetest.register_node(":technic:concrete", {
description = S("Concrete Block"),
tile_images = {"technic_concrete_block.png",},
tiles = {"technic_concrete_block.png",},
groups = {cracky=1, level=2, concrete=1},
sounds = default.node_sound_stone_defaults(),
after_place_node = function(pos, placer, itemstack)
technic.update_posts(pos, false)
end,
after_dig_node = function (pos, oldnode, oldmetadata, digger)
technic.update_posts(pos, false)
end,
})
minetest.register_node(":technic:blast_resistant_concrete", {
description = S("Blast-resistant Concrete Block"),
tile_images = {"technic_blast_resistant_concrete_block.png",},
groups={cracky=1, level=3, concrete=1},
tiles = {"technic_blast_resistant_concrete_block.png",},
groups = {cracky=1, level=3, concrete=1},
sounds = default.node_sound_stone_defaults(),
after_place_node = function(pos, player, itemstack)
technic.update_posts(pos, false)
end,
after_dig_node = function (pos, oldnode, oldmetadata, digger)
technic.update_posts(pos, false)
on_blast = function(pos, intensity)
if intensity > 9 then
minetest.remove_node(pos)
return {"technic:blast_resistant_concrete"}
end
end,
})
local box_platform = {-0.5, 0.3, -0.5, 0.5, 0.5, 0.5}
local box_post = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}
local box_front = {-0.1, -0.3, -0.5, 0.1, 0.3, 0}
local box_back = {-0.1, -0.3, 0, 0.1, 0.3, 0.5}
local box_left = {-0.5, -0.3, -0.1, 0, 0.3, 0.1}
local box_right = {0, -0.3, -0.1, 0.5, 0.3, 0.1}
minetest.register_node(":technic:concrete_post_platform", {
description = S("Concrete Post Platform"),
tile_images = {"technic_concrete_block.png",},
tiles = {"technic_concrete_block.png",},
groups={cracky=1, level=2},
sounds = default.node_sound_stone_defaults(),
paramtype = "light",
@ -119,144 +112,45 @@ minetest.register_node(":technic:concrete_post_platform", {
},
on_place = function (itemstack, placer, pointed_thing)
local node = minetest.get_node(pointed_thing.under)
if not technic.concrete_posts[node.name] then
if node.name ~= "technic:concrete_post" then
return minetest.item_place_node(itemstack, placer, pointed_thing)
end
local links = technic.concrete_posts[node.name]
if links[5] ~= 0 then -- The post already has a platform
return minetest.item_place_node(itemstack, placer, pointed_thing)
end
local id = technic.get_post_id({links[1], links[2], links[3], links[4], 1})
minetest.set_node(pointed_thing.under, {name="technic:concrete_post"..id})
minetest.set_node(pointed_thing.under, {name="technic:concrete_post_with_platform"})
itemstack:take_item()
placer:set_wielded_item(itemstack)
return itemstack
end,
})
local function gen_post_nodebox(x1, x2, z1, z2, platform)
local box = {box_center}
if x1 ~= 0 then
table.insert(box, box_x1)
end
if x2 ~= 0 then
table.insert(box, box_x2)
end
if z1 ~= 0 then
table.insert(box, box_z1)
end
if z2 ~= 0 then
table.insert(box, box_z2)
end
if platform ~= 0 then
table.insert(box, box_platform)
end
return box
end
local function dig_post_with_platform(pos, oldnode, oldmetadata)
oldnode.name = "technic:concrete_post0"
minetest.set_node(pos, oldnode)
technic.update_posts(pos, true)
end
function technic.posts_should_connect(pos)
local node = minetest.get_node(pos)
if technic.concrete_posts[node.name] then
return "post"
elseif minetest.get_item_group(node.name, "concrete") ~= 0 then
return "block"
end
end
function technic.get_post_id(links)
return (links[4] * 1) + (links[3] * 2)
+ (links[2] * 4) + (links[1] * 8)
+ (links[5] * 16)
end
function technic.update_posts(pos, set, secondrun)
local node = minetest.get_node(pos)
local link_positions = {
{x=pos.x+1, y=pos.y, z=pos.z},
{x=pos.x-1, y=pos.y, z=pos.z},
{x=pos.x, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1},
}
local links = {0, 0, 0, 0, 0}
for i, link_pos in pairs(link_positions) do
local connecttype = technic.posts_should_connect(link_pos)
if connecttype then
links[i] = 1
-- Have posts next to us update theirselves,
-- but only once. (We don't want to start an
-- infinite loop of updates)
if not secondrun and connecttype == "post" then
technic.update_posts(link_pos, true, true)
end
end
end
-- We don't want to set ourselves if we have been removed or we are
-- updating a concrete node
if set then
-- Preserve platform
local oldlinks = technic.concrete_posts[node.name]
if oldlinks then
links[5] = oldlinks[5]
end
minetest.set_node(pos, {name="technic:concrete_post"
..technic.get_post_id(links)})
end
end
for x1 = 0, 1 do
for x2 = 0, 1 do
for z1 = 0, 1 do
for z2 = 0, 1 do
for platform = 0, 1 do
local links = {x1, x2, z1, z2, platform}
local id = technic.get_post_id(links)
technic.concrete_posts["technic:concrete_post"..id] = links
local groups = {cracky=1, level=2, concrete_post=1}
if id ~= 0 then
groups.not_in_creative_inventory = 1
end
local drop = "technic:concrete_post0"
local after_dig_node = function(pos, oldnode, oldmetadata, digger)
technic.update_posts(pos, false)
end
if platform ~= 0 then
drop = "technic:concrete_post_platform"
after_dig_node = function(pos, oldnode, oldmetadata, digger)
dig_post_with_platform(pos, oldnode, oldmetadata)
local after_dig_node = nil
if platform == 1 then
after_dig_node = function(pos, old_node)
old_node.name = "technic:concrete_post"
minetest.set_node(pos, old_node)
end
end
minetest.register_node(":technic:concrete_post"..id, {
minetest.register_node(":technic:concrete_post"..(platform == 1 and "_with_platform" or ""), {
description = S("Concrete Post"),
tiles = {"technic_concrete_block.png"},
groups = groups,
groups = {cracky=1, level=2, concrete_post=1, not_in_creative_inventory=platform},
sounds = default.node_sound_stone_defaults(),
drop = drop,
drop = (platform == 1 and "technic:concrete_post_platform" or
"technic:concrete_post"),
paramtype = "light",
sunlight_propagates = true,
drawtype = "nodebox",
drawtype = "nodebox",
connects_to = {"group:concrete", "group:concrete_post"},
node_box = {
type = "fixed",
fixed = gen_post_nodebox(x1, x2, z1, z2, platform),
type = "connected",
fixed = {box_post, (platform == 1 and box_platform or nil)},
connect_front = box_front,
connect_back = box_back,
connect_left = box_left,
connect_right = box_right,
},
after_place_node = function(pos, placer, itemstack)
technic.update_posts(pos, true)
end,
after_dig_node = after_dig_node,
})
end
end
end
end
end

8
concrete/locale/es.txt Normal file
View File

@ -0,0 +1,8 @@
# technic_concrete traducido por Carlos Barraza
Rebar = Barra de refuerzo
Concrete Block = Bloque de concreto
Blast-resistant Concrete Block = Bloque de concreto resistente a explosiones
Concrete Post Platform = Plataforma de concreto
Concrete Post = Postes de concreto

7
concrete/locale/tr.txt Normal file
View File

@ -0,0 +1,7 @@
# turkish translation by mahmutelmas06
Rebar = Beton demiri
Concrete Block = Beton blok
Blast-resistant Concrete Block = Patlamaya dayanıklı beton blok
Concrete Post Platform = Beton direk platformu
Concrete Post = Beton direk

View File

@ -1,6 +1,6 @@
default
moreblocks
technic_worldgen
concrete
unifieddyes?
intllib?
moreblocks?

View File

@ -1,86 +1,187 @@
-- Minetest 0.4.6 mod: extranodes
-- namespace: technic
-- Boilerplate to support localized strings if intllib mod is installed.
local S
if intllib then
S = intllib.Getter()
else
S = function(s) return s end
local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
if minetest.get_modpath("moreblocks") then
-- register stairsplus/circular_saw nodes
-- we skip blast resistant concrete and uranium intentionally
-- chrome seems to be too hard of a metal to be actually sawable
stairsplus:register_all("technic", "marble", "technic:marble", {
description=S("Marble"),
groups={cracky=3, not_in_creative_inventory=1},
tiles={"technic_marble.png"},
})
stairsplus:register_all("technic", "marble_bricks", "technic:marble_bricks", {
description=S("Marble Bricks"),
groups={cracky=3, not_in_creative_inventory=1},
tiles={"technic_marble_bricks.png"},
})
stairsplus:register_all("technic", "granite", "technic:granite", {
description=S("Granite"),
groups={cracky=1, not_in_creative_inventory=1},
tiles={"technic_granite.png"},
})
stairsplus:register_all("technic", "concrete", "technic:concrete", {
description=S("Concrete"),
groups={cracky=3, not_in_creative_inventory=1},
tiles={"technic_concrete_block.png"},
})
stairsplus:register_all("technic", "zinc_block", "technic:zinc_block", {
description=S("Zinc Block"),
groups={cracky=1, not_in_creative_inventory=1},
tiles={"technic_zinc_block.png"},
})
stairsplus:register_all("technic", "cast_iron_block", "technic:cast_iron_block", {
description=S("Cast Iron Block"),
groups={cracky=1, not_in_creative_inventory=1},
tiles={"technic_cast_iron_block.png"},
})
stairsplus:register_all("technic", "carbon_steel_block", "technic:carbon_steel_block", {
description=S("Carbon Steel Block"),
groups={cracky=1, not_in_creative_inventory=1},
tiles={"technic_carbon_steel_block.png"},
})
stairsplus:register_all("technic", "stainless_steel_block", "technic:stainless_steel_block", {
description=S("Stainless Steel Block"),
groups={cracky=1, not_in_creative_inventory=1},
tiles={"technic_stainless_steel_block.png"},
})
stairsplus:register_all("technic", "brass_block", "technic:brass_block", {
description=S("Brass Block"),
groups={cracky=1, not_in_creative_inventory=1},
tiles={"technic_brass_block.png"},
})
function register_technic_stairs_alias(modname, origname, newmod, newname)
minetest.register_alias(modname .. ":slab_" .. origname, newmod..":slab_" .. newname)
minetest.register_alias(modname .. ":slab_" .. origname .. "_inverted", newmod..":slab_" .. newname .. "_inverted")
minetest.register_alias(modname .. ":slab_" .. origname .. "_wall", newmod..":slab_" .. newname .. "_wall")
minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter", newmod..":slab_" .. newname .. "_quarter")
minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter_inverted", newmod..":slab_" .. newname .. "_quarter_inverted")
minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter_wall", newmod..":slab_" .. newname .. "_quarter_wall")
minetest.register_alias(modname .. ":slab_" .. origname .. "_three_quarter", newmod..":slab_" .. newname .. "_three_quarter")
minetest.register_alias(modname .. ":slab_" .. origname .. "_three_quarter_inverted", newmod..":slab_" .. newname .. "_three_quarter_inverted")
minetest.register_alias(modname .. ":slab_" .. origname .. "_three_quarter_wall", newmod..":slab_" .. newname .. "_three_quarter_wall")
minetest.register_alias(modname .. ":stair_" .. origname, newmod..":stair_" .. newname)
minetest.register_alias(modname .. ":stair_" .. origname .. "_inverted", newmod..":stair_" .. newname .. "_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall", newmod..":stair_" .. newname .. "_wall")
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half", newmod..":stair_" .. newname .. "_wall_half")
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half_inverted", newmod..":stair_" .. newname .. "_wall_half_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_half", newmod..":stair_" .. newname .. "_half")
minetest.register_alias(modname .. ":stair_" .. origname .. "_half_inverted", newmod..":stair_" .. newname .. "_half_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_right_half", newmod..":stair_" .. newname .. "_right_half")
minetest.register_alias(modname .. ":stair_" .. origname .. "_right_half_inverted", newmod..":stair_" .. newname .. "_right_half_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half", newmod..":stair_" .. newname .. "_wall_half")
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half_inverted", newmod..":stair_" .. newname .. "_wall_half_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_inner", newmod..":stair_" .. newname .. "_inner")
minetest.register_alias(modname .. ":stair_" .. origname .. "_inner_inverted", newmod..":stair_" .. newname .. "_inner_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_outer", newmod..":stair_" .. newname .. "_outer")
minetest.register_alias(modname .. ":stair_" .. origname .. "_outer_inverted", newmod..":stair_" .. newname .. "_outer_inverted")
minetest.register_alias(modname .. ":panel_" .. origname .. "_bottom", newmod..":panel_" .. newname .. "_bottom")
minetest.register_alias(modname .. ":panel_" .. origname .. "_top", newmod..":panel_" .. newname .. "_top")
minetest.register_alias(modname .. ":panel_" .. origname .. "_vertical", newmod..":panel_" .. newname .. "_vertical")
minetest.register_alias(modname .. ":micro_" .. origname .. "_bottom", newmod..":micro_" .. newname .. "_bottom")
minetest.register_alias(modname .. ":micro_" .. origname .. "_top", newmod..":micro_" .. newname .. "_top")
end
register_technic_stairs_alias("stairsplus", "concrete", "technic", "concrete")
register_technic_stairs_alias("stairsplus", "marble", "technic", "marble")
register_technic_stairs_alias("stairsplus", "granite", "technic", "granite")
register_technic_stairs_alias("stairsplus", "marble_bricks", "technic", "marble_bricks")
end
--register stairslike nodes
register_stair_slab_panel_micro("technic", "marble", "technic:marble",
{cracky=2, not_in_creative_inventory=1},
{"technic_marble.png"},
S("Marble"),
"marble",
"facedir",
0)
register_stair_slab_panel_micro("technic", "marble_bricks", "technic:marble_bricks",
{cracky=2, not_in_creative_inventory=1},
{"technic_marble_bricks.png"},
S("Marble Bricks"),
"marble_bricks",
"facedir",
0)
local iclip_def = {
description = "Insulator/cable clip",
drawtype = "mesh",
mesh = "technic_insulator_clip.obj",
tiles = {"technic_insulator_clip.png"},
is_ground_content = false,
groups = {choppy=1, snappy=1, oddly_breakable_by_hand=1 },
sounds = default.node_sound_stone_defaults(),
}
register_stair_slab_panel_micro("technic", "granite", "technic:granite",
{cracky=3, not_in_creative_inventory=1},
{"technic_granite.png"},
S("Granite"),
"granite",
"facedir",
0)
local iclipfence_def = {
description = "Insulator/cable clip",
tiles = {"technic_insulator_clip.png"},
is_ground_content = false,
paramtype = "light",
drawtype = "nodebox",
node_box = {
type = "connected",
fixed = {
{ -0.25, 0.75, -0.25, 0.25, 1.25, 0.25 }, -- the clip on top
{ -0.125, 0.6875, -0.125, 0.125, 0.75, 0.125 },
{ -0.1875, 0.625, -0.1875, 0.1875, 0.6875, 0.1875 },
{ -0.125, 0.5625, -0.125, 0.125, 0.625, 0.125 },
{ -0.1875, 0.5, -0.1875, 0.1875, 0.5625, 0.1875 },
{ -0.125, 0.4375, -0.125, 0.125, 0.5, 0.125 },
{ -0.1875, 0.375, -0.1875, 0.1875, 0.4375, 0.1875 },
{ -0.125, -0.5, -0.125, 0.125, 0.375, 0.125 }, -- the post, slightly short
},
-- connect_top =
-- connect_bottom =
connect_front = {{-1/16,3/16,-1/2,1/16,5/16,-1/8},
{-1/16,-5/16,-1/2,1/16,-3/16,-1/8}},
connect_left = {{-1/2,3/16,-1/16,-1/8,5/16,1/16},
{-1/2,-5/16,-1/16,-1/8,-3/16,1/16}},
connect_back = {{-1/16,3/16,1/8,1/16,5/16,1/2},
{-1/16,-5/16,1/8,1/16,-3/16,1/2}},
connect_right = {{1/8,3/16,-1/16,1/2,5/16,1/16},
{1/8,-5/16,-1/16,1/2,-3/16,1/16}},
},
connects_to = {"group:fence", "group:wood", "group:tree"},
groups = {fence=1, choppy=1, snappy=1, oddly_breakable_by_hand=1 },
sounds = default.node_sound_stone_defaults(),
}
register_stair_slab_panel_micro("technic", "concrete", "technic:concrete",
{cracky=3, not_in_creative_inventory=1},
{"technic_concrete_block.png"},
S("Concrete"),
"concrete",
"facedir",
0)
--register nodes in circular saw if aviable
if circular_saw then
for i,v in ipairs({"concrete", "marble", "marble_bricks", "granite", "default:obsidian"}) do
table.insert(circular_saw.known_stairs, "technic:" ..v);
if minetest.get_modpath("unifieddyes") then
iclip_def.paramtype2 = "colorwallmounted"
iclip_def.palette = "unifieddyes_palette_colorwallmounted.png"
iclip_def.after_place_node = function(pos, placer, itemstack, pointed_thing)
unifieddyes.fix_rotation(pos, placer, itemstack, pointed_thing)
unifieddyes.recolor_on_place(pos, placer, itemstack, pointed_thing)
end
iclip_def.after_dig_node = unifieddyes.after_dig_node
iclip_def.groups = {choppy=1, snappy=1, oddly_breakable_by_hand=1, ud_param2_colorable = 1}
iclipfence_def.paramtype2 = "color"
iclipfence_def.palette = "unifieddyes_palette_extended.png"
iclipfence_def.on_construct = unifieddyes.on_construct
iclipfence_def.after_place_node = unifieddyes.recolor_on_place
iclipfence_def.after_dig_node = unifieddyes.after_dig_node
iclipfence_def.groups = {fence=1, choppy=1, snappy=1, oddly_breakable_by_hand=1, ud_param2_colorable = 1}
iclipfence_def.place_param2 = 171 -- medium amber, low saturation, closest color to default:wood
end
function register_technic_stairs_alias(modname, origname, newmod, newname)
minetest.register_alias(modname .. ":slab_" .. origname, newmod..":slab_" .. newname)
minetest.register_alias(modname .. ":slab_" .. origname .. "_inverted", newmod..":slab_" .. newname .. "_inverted")
minetest.register_alias(modname .. ":slab_" .. origname .. "_wall", newmod..":slab_" .. newname .. "_wall")
minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter", newmod..":slab_" .. newname .. "_quarter")
minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter_inverted", newmod..":slab_" .. newname .. "_quarter_inverted")
minetest.register_alias(modname .. ":slab_" .. origname .. "_quarter_wall", newmod..":slab_" .. newname .. "_quarter_wall")
minetest.register_alias(modname .. ":slab_" .. origname .. "_three_quarter", newmod..":slab_" .. newname .. "_three_quarter")
minetest.register_alias(modname .. ":slab_" .. origname .. "_three_quarter_inverted", newmod..":slab_" .. newname .. "_three_quarter_inverted")
minetest.register_alias(modname .. ":slab_" .. origname .. "_three_quarter_wall", newmod..":slab_" .. newname .. "_three_quarter_wall")
minetest.register_alias(modname .. ":stair_" .. origname, newmod..":stair_" .. newname)
minetest.register_alias(modname .. ":stair_" .. origname .. "_inverted", newmod..":stair_" .. newname .. "_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall", newmod..":stair_" .. newname .. "_wall")
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half", newmod..":stair_" .. newname .. "_wall_half")
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half_inverted", newmod..":stair_" .. newname .. "_wall_half_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_half", newmod..":stair_" .. newname .. "_half")
minetest.register_alias(modname .. ":stair_" .. origname .. "_half_inverted", newmod..":stair_" .. newname .. "_half_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_right_half", newmod..":stair_" .. newname .. "_right_half")
minetest.register_alias(modname .. ":stair_" .. origname .. "_right_half_inverted", newmod..":stair_" .. newname .. "_right_half_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half", newmod..":stair_" .. newname .. "_wall_half")
minetest.register_alias(modname .. ":stair_" .. origname .. "_wall_half_inverted", newmod..":stair_" .. newname .. "_wall_half_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_inner", newmod..":stair_" .. newname .. "_inner")
minetest.register_alias(modname .. ":stair_" .. origname .. "_inner_inverted", newmod..":stair_" .. newname .. "_inner_inverted")
minetest.register_alias(modname .. ":stair_" .. origname .. "_outer", newmod..":stair_" .. newname .. "_outer")
minetest.register_alias(modname .. ":stair_" .. origname .. "_outer_inverted", newmod..":stair_" .. newname .. "_outer_inverted")
minetest.register_alias(modname .. ":panel_" .. origname .. "_bottom", newmod..":panel_" .. newname .. "_bottom")
minetest.register_alias(modname .. ":panel_" .. origname .. "_top", newmod..":panel_" .. newname .. "_top")
minetest.register_alias(modname .. ":panel_" .. origname .. "_vertical", newmod..":panel_" .. newname .. "_vertical")
minetest.register_alias(modname .. ":micro_" .. origname .. "_bottom", newmod..":micro_" .. newname .. "_bottom")
minetest.register_alias(modname .. ":micro_" .. origname .. "_top", newmod..":micro_" .. newname .. "_top")
end
minetest.register_node(":technic:insulator_clip", iclip_def)
minetest.register_node(":technic:insulator_clip_fencepost", iclipfence_def)
register_technic_stairs_alias("stairsplus", "concrete", "technic", "concrete")
register_technic_stairs_alias("stairsplus", "marble", "technic", "marble")
register_technic_stairs_alias("stairsplus", "granite", "technic", "granite")
register_technic_stairs_alias("stairsplus", "marble_bricks", "technic", "marble_bricks")
minetest.register_craft({
output = "technic:insulator_clip",
recipe = {
{ "", "dye:white", ""},
{ "", "technic:raw_latex", ""},
{ "technic:raw_latex", "default:stone", "technic:raw_latex"},
}
})
minetest.register_craft({
output = "technic:insulator_clip_fencepost 2",
recipe = {
{ "", "dye:white", ""},
{ "", "technic:raw_latex", ""},
{ "technic:raw_latex", "default:fence_wood", "technic:raw_latex"},
}
})

7
extranodes/locale/es.txt Normal file
View File

@ -0,0 +1,7 @@
# technic_extranodes traducido por Carlos Barraza
Marble = Mármol
Marble Bricks = Ladrillos de mármol
Granite = Granito
Concrete = Concreto

6
extranodes/locale/tr.txt Normal file
View File

@ -0,0 +1,6 @@
# turkish translation by mahmutelmas06
Marble = Mermer
Marble Bricks = Mermer tuğla
Granite = Granit
Concrete = Beton

View File

@ -0,0 +1,173 @@
# Blender v2.72 (sub 0) OBJ File: ''
# www.blender.org
o Cube
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 0.500000
v -0.249997 0.500000 0.249997
v -0.249997 0.500000 -0.249997
v 0.249997 0.500000 -0.249997
v 0.249997 0.500000 0.249997
v -0.187500 0.500000 0.187500
v -0.187500 0.500000 -0.187500
v 0.187500 0.500000 -0.187500
v 0.187500 0.500000 0.187500
v -0.187500 0.750000 0.187500
v -0.187500 0.750000 -0.187500
v 0.187500 0.750000 -0.187500
v 0.187500 0.750000 0.187500
v -0.250000 0.750000 0.250000
v -0.250000 0.750000 -0.250000
v 0.250000 0.750000 -0.250000
v 0.250000 0.750000 0.250000
v -0.250000 1.250000 0.250000
v -0.250000 1.250000 -0.250000
v 0.250000 1.250000 -0.250000
v 0.250000 1.250000 0.250000
v -0.500000 0.312500 0.500000
v -0.500000 0.312500 -0.500000
v 0.500000 0.312500 -0.500000
v 0.500000 0.312500 0.500000
v 0.187500 0.625000 0.187500
v 0.187500 0.625000 -0.187500
v -0.187500 0.625000 -0.187500
v -0.187500 0.625000 0.187500
v 0.187500 0.562500 0.187500
v 0.187500 0.687500 -0.187500
v -0.187500 0.687500 -0.187500
v -0.187500 0.562500 0.187500
v 0.187500 0.687500 0.187500
v 0.187500 0.562500 -0.187500
v -0.187500 0.562500 -0.187500
v -0.187500 0.687500 0.187500
v 0.168668 0.531250 0.168668
v 0.168668 0.718750 -0.168668
v -0.168668 0.718750 -0.168668
v -0.168668 0.531250 0.168668
v 0.168668 0.656250 0.168668
v 0.168668 0.593750 -0.168668
v -0.168668 0.593750 -0.168668
v -0.168668 0.656250 0.168668
v 0.168668 0.593750 0.168668
v 0.168668 0.656250 -0.168668
v -0.168668 0.656250 -0.168668
v -0.168668 0.593750 0.168668
v 0.168668 0.718750 0.168668
v 0.168668 0.531250 -0.168668
v -0.168668 0.531250 -0.168668
v -0.168668 0.718750 0.168668
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 0.749997 0.749997
vt 0.749997 0.250003
vt 0.250003 0.250003
vt 0.250003 0.749997
vt 0.000000 0.812500
vt 1.000000 0.812500
vt 0.312500 0.312500
vt 0.312500 0.687500
vt 0.687500 0.312500
vt 0.687500 0.687500
vt 0.331332 1.218750
vt 0.668668 1.218750
vt 0.687500 1.250000
vt 0.312500 1.250000
vt 0.750000 1.250000
vt 0.750000 1.750000
vt 0.250000 1.750000
vt 0.250000 1.250000
vt 0.331332 1.093750
vt 0.668668 1.093750
vt 0.687500 1.125000
vt 0.312500 1.125000
vt 0.331332 1.093750
vt 0.668668 1.093750
vt 0.331332 1.156250
vt 0.668668 1.156250
vt 0.687500 1.187500
vt 0.312500 1.187500
vt 0.331332 1.156250
vt 0.668668 1.156250
vt 0.331332 1.031250
vt 0.668668 1.031250
vt 0.687500 1.062500
vt 0.312500 1.062500
vt 0.312500 1.000000
vt 0.687500 1.000000
vn 0.000000 -1.000000 -0.000000
vn -0.600000 0.800000 -0.000000
vn 0.000000 0.800000 -0.600000
vn 0.600000 0.800000 0.000000
vn -0.000000 0.000000 1.000000
vn 0.000000 1.000000 0.000000
vn 0.856500 -0.516200 0.000000
vn 0.000000 -0.516200 -0.856500
vn -0.000000 -0.516200 0.856500
vn -0.856500 -0.516200 -0.000000
vn -1.000000 0.000000 -0.000000
vn 0.000000 -0.000000 -1.000000
vn 1.000000 -0.000000 0.000000
vn -0.000000 0.800000 0.600000
vn 0.856500 0.516200 0.000000
vn 0.000000 0.516200 -0.856500
vn -0.000000 0.516200 0.856500
vn -0.856500 0.516200 -0.000000
g Cube_Cube_Material
s off
f 1/1/1 2/2/1 3/3/1 4/4/1
f 25/2/2 5/5/2 6/6/2 26/1/2
f 26/1/3 6/6/3 7/7/3 27/4/3
f 27/4/4 7/7/4 8/8/4 28/3/4
f 25/9/5 1/4/5 4/1/5 28/10/5
f 8/8/6 7/7/6 11/11/6 12/12/6
f 7/7/6 6/6/6 10/13/6 11/11/6
f 5/5/6 8/8/6 12/12/6 9/14/6
f 6/6/6 5/5/6 9/14/6 10/13/6
f 53/15/7 42/16/7 15/17/7 16/18/7
f 42/15/8 43/16/8 14/17/8 15/18/8
f 56/15/9 53/16/9 16/17/9 13/18/9
f 43/15/10 56/16/10 13/17/10 14/18/10
f 14/4/1 18/4/1 19/4/1 15/4/1
f 17/19/11 21/20/11 22/21/11 18/22/11
f 18/19/12 22/20/12 23/21/12 19/22/12
f 19/19/13 23/20/13 24/21/13 20/22/13
f 21/21/5 17/22/5 20/19/5 24/20/5
f 21/5/6 24/8/6 23/7/6 22/6/6
f 15/4/1 19/4/1 20/4/1 16/4/1
f 16/4/1 20/4/1 17/4/1 13/4/1
f 13/4/1 17/4/1 18/4/1 14/4/1
f 1/1/11 25/10/11 26/9/11 2/4/11
f 2/1/12 26/10/12 27/9/12 3/4/12
f 3/1/13 27/10/13 28/9/13 4/4/13
f 5/5/14 25/2/14 28/3/14 8/8/14
f 49/23/7 46/24/7 30/25/7 29/26/7
f 46/27/8 47/28/8 31/25/8 30/26/8
f 52/23/9 49/24/9 29/25/9 32/26/9
f 47/23/10 52/24/10 32/25/10 31/26/10
f 45/29/7 50/30/7 34/31/7 37/32/7
f 50/33/8 51/34/8 35/31/8 34/32/8
f 48/33/9 45/34/9 37/31/9 40/32/9
f 51/29/10 48/30/10 40/31/10 35/32/10
f 41/35/7 54/36/7 38/37/7 33/38/7
f 54/35/8 55/36/8 39/37/8 38/38/8
f 44/35/9 41/36/9 33/37/9 36/38/9
f 55/35/10 44/36/10 36/37/10 39/38/10
f 37/32/15 34/31/15 42/16/15 53/15/15
f 34/32/16 35/31/16 43/16/16 42/15/16
f 40/32/17 37/31/17 53/16/17 56/15/17
f 35/32/18 40/31/18 56/16/18 43/15/18
f 33/38/15 38/37/15 46/24/15 49/23/15
f 38/38/16 39/37/16 47/28/16 46/27/16
f 36/38/17 33/37/17 49/24/17 52/23/17
f 39/38/18 36/37/18 52/24/18 47/23/18
f 29/26/15 30/25/15 50/30/15 45/29/15
f 30/26/16 31/25/16 51/34/16 50/33/16
f 32/26/17 29/25/17 45/34/17 48/33/17
f 31/26/18 32/25/18 48/30/18 51/29/18
f 12/39/15 11/40/15 54/36/15 41/35/15
f 11/39/16 10/40/16 55/36/16 54/35/16
f 9/39/17 12/40/17 41/36/17 44/35/17
f 10/39/18 9/40/18 44/36/18 55/35/18

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

1493
manual.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,68 +0,0 @@
Notes on iron and steel
=======================
Alloying iron with carbon is of huge importance, but in some processes
the alloying is an implicit side effect rather than the product of
explicit mixing, so it is a complex area. In the real world, there is
a huge variety of kinds of iron and steel, differing in the proportion
of carbon included and in other elements added to the mix.
The Minetest default mod doesn't distinguish between types of iron and
steel at all. This mod introduces multiple types in order to get a bit
of complexity and flavour.
Leaving aside explicit addition of other elements, the iron/carbon
spectrum is here represented by three 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. 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. 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. 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,
armour, skyscrapers, large bridges, and machines.
Historically, the first form of iron to be refined was wrought iron,
produced from ore by a low-temperature furnace process in which the
ore/iron remains solid and impurities (slag) are progressively removed.
Cast iron, by contrast, was produced somewhat later by a high-temperature
process in a blast furnace, in which the metal is melted, and carbon is
unavoidably incorporated from the furnace's fuel. (In fact, it's done
in two stages, first producing pig iron from ore, and then remelting the
pig iron to cast as cast iron.) Carbon steel requires a more advanced
process, in which molten pig iron is processed to remove the carbon,
and then a controlled amount of carbon is explicitly mixed back in.
Other processes are possible to refine iron ore and to adjust its
carbon content.
Unfortunately, Minetest doesn't let us readily distinguish between
low-temperature and high-temperature processes: in the default game, the
same furnace is used both to cook food (low temperature) and to cast metal
ingots (varying high temperatures). So we can't sensibly have wrought
iron and cast iron produced by different types of furnace. Nor can
furnace recipes discriminate by which kind of fuel is used (and thus
by the availability of carbon). The alloy furnace allows for explicit
alloying, which appropriately represents how carbon steel is made, but
is not sensible for the other two, and is a relatively advanced process.
About the only option to make a second iron-processing furnace process
readily available is to cook multiple times; happily, this bears a slight
resemblance to the real process with pig iron as an intermediate product.
The default mod's refined iron, which it calls "steel", is identified
with this mod's wrought iron. Cooking an iron lump (representing ore)
initially produces wrought iron; the cooking process here represents a
low-temperature bloomery process. Cooking wrought iron then produces
cast iron; this time the cooking process represents a blast furnace.
Alloy cooking wrought iron with coal dust (carbon) produces carbon steel;
this represents the explicit mixing stage of carbon steel production.
Additionally, alloy cooking carbon steel with coal dust produces cast
iron, which is logical but not very useful. Furthermore, to make it
possible to turn any of the forms of iron into any other, cooking carbon
steel or cast iron produces wrought iron, in an abbreviated form of the
bloomery process. As usual for metals, the same cooking and alloying
processes can be performed in parallel forms on ingots or dust.

View File

@ -10,6 +10,26 @@ Technic chests code is licensed under the GNU LGPLv2+.
Texture licenses:
RealBadAngel: (WTFPL)
* Everything.
BlockMen modified by Zefram (CC BY-SA 3.0):
* technic_chernobylite_block.png
* technic_corium_flowing_animated.png
* technic_corium_source_animated.png
celeron55 (Perttu Ahola) modified by Zefram (CC BY-SA 3.0):
* technic_bucket_corium.png
sdzen (Elise Staudter) (CC BY-SA 3.0):
* most of the older 16x16 textures
RealBadAngel: (WTFPL)
* Everything else.
CC BY-SA 3.0: <http://creativecommons.org/licenses/by-sa/3.0/>
Sound licenses:
veikk0 (Veikko Mäkelä) (CC BY-SA 4.0):
* technic_hv_nuclear_reactor_siren_danger_loop.ogg
* Derived from "Nuclear alarm.wav" by Freesound.org user rene___ from <https://freesound.org/people/rene___/sounds/56778/>. Originally licensed under CC0 1.0 <https://creativecommons.org/publicdomain/zero/1.0/>
CC BY-SA 4.0: <https://creativecommons.org/licenses/by-sa/4.0/>

View File

@ -1,7 +1,4 @@
local worldpath = minetest.get_worldpath()
technic.config = Settings(worldpath.."/technic.conf")
technic.config = technic.config or Settings(minetest.get_worldpath().."/technic.conf")
local conf_table = technic.config:to_table()
@ -9,10 +6,13 @@ local defaults = {
enable_mining_drill = "true",
enable_mining_laser = "true",
enable_flashlight = "false",
enable_rubber_tree_generation = "true",
enable_marble_generation = "true",
enable_granite_generation = "true",
enable_wind_mill = "false",
enable_frames = "false",
enable_corium_griefing = "true",
enable_radiation_protection = "true",
enable_entity_radiation_damage = "true",
enable_longterm_radiation_damage = "true",
enable_nuclear_reactor_digiline_selfdestruct = "false",
}
for k, v in pairs(defaults) do
@ -20,4 +20,3 @@ for k, v in pairs(defaults) do
technic.config:set(k, v)
end
end

View File

@ -1,21 +1,45 @@
-- check if we have the necessary dependencies to allow actually using these materials in the crafts
local mesecons_materials = minetest.get_modpath("mesecons_materials")
-- Remove some recipes
-- Bronze
minetest.clear_craft({
type = "shapeless",
output = "default:bronze_ingot"
})
-- Accelerator tube
if pipeworks.enable_accelerator_tube then
minetest.clear_craft({
output = "pipeworks:accelerator_tube_1",
})
minetest.register_craft({
output = 'pipeworks:accelerator_tube_1',
recipe = {
{'technic:copper_coil', 'pipeworks:tube_1', 'technic:copper_coil'},
}
})
end
-- Teleport tube
if pipeworks.enable_teleport_tube then
minetest.clear_craft({
output = "pipeworks:teleport_tube_1",
})
minetest.register_craft({
output = 'pipeworks:teleport_tube_1',
recipe = {
{'default:mese_crystal', 'technic:copper_coil', 'default:mese_crystal'},
{'pipeworks:tube_1', 'technic:control_logic_unit', 'pipeworks:tube_1'},
{'default:mese_crystal', 'technic:copper_coil', 'default:mese_crystal'},
}
})
end
-- tubes crafting recipes
minetest.register_craft({
output = 'pipeworks:accelerator_tube_1',
recipe = {
{'technic:copper_coil', 'pipeworks:tube_1', 'technic:copper_coil'},
}
})
minetest.register_craft({
output = 'pipeworks:teleport_tube_1',
recipe = {
{'default:mese_crystal', 'technic:copper_coil', 'default:mese_crystal'},
{'pipeworks:tube_1', 'technic:control_logic_unit', 'pipeworks:tube_1'},
{'default:mese_crystal', 'technic:copper_coil', 'default:mese_crystal'},
}
})
minetest.register_craft({
output = 'technic:diamond_drill_head',
recipe = {
@ -37,18 +61,18 @@ minetest.register_craft({
minetest.register_craft({
output = 'technic:blue_energy_crystal',
recipe = {
{'default:gold_ingot', 'technic:battery', 'dye:blue'},
{'moreores:mithril_ingot', 'technic:battery', 'dye:blue'},
{'technic:battery', 'technic:green_energy_crystal', 'technic:battery'},
{'dye:blue', 'technic:battery', 'default:gold_ingot'},
{'dye:blue', 'technic:battery', 'moreores:mithril_ingot'},
}
})
minetest.register_craft({
output = 'technic:red_energy_crystal',
recipe = {
{'default:gold_ingot', 'technic:battery', 'dye:red'},
{'moreores:silver_ingot', 'technic:battery', 'dye:red'},
{'technic:battery', 'default:diamondblock', 'technic:battery'},
{'dye:red', 'technic:battery', 'default:gold_ingot'},
{'dye:red', 'technic:battery', 'moreores:silver_ingot'},
}
})
@ -61,6 +85,24 @@ minetest.register_craft({
}
})
minetest.register_craft({
output = 'technic:fine_gold_wire 2',
recipe = {
{'', 'default:gold_ingot', ''},
{'', 'default:gold_ingot', ''},
{'', 'default:gold_ingot', ''},
}
})
minetest.register_craft({
output = 'technic:fine_silver_wire 2',
recipe = {
{'', 'moreores:silver_ingot', ''},
{'', 'moreores:silver_ingot', ''},
{'', 'moreores:silver_ingot', ''},
}
})
minetest.register_craft({
output = 'technic:copper_coil 1',
recipe = {
@ -79,10 +121,12 @@ minetest.register_craft({
}
})
local isolation = mesecons_materials and "mesecons_materials:fiber" or "technic:rubber"
minetest.register_craft({
output = 'technic:lv_transformer',
recipe = {
{'technic:wrought_iron_ingot', 'technic:wrought_iron_ingot', 'technic:wrought_iron_ingot'},
{isolation, 'technic:wrought_iron_ingot', isolation},
{'technic:copper_coil', 'technic:wrought_iron_ingot', 'technic:copper_coil'},
{'technic:wrought_iron_ingot', 'technic:wrought_iron_ingot', 'technic:wrought_iron_ingot'},
}
@ -91,7 +135,7 @@ minetest.register_craft({
minetest.register_craft({
output = 'technic:mv_transformer',
recipe = {
{'technic:carbon_steel_ingot', 'technic:carbon_steel_ingot', 'technic:carbon_steel_ingot'},
{isolation, 'technic:carbon_steel_ingot', isolation},
{'technic:copper_coil', 'technic:carbon_steel_ingot', 'technic:copper_coil'},
{'technic:carbon_steel_ingot', 'technic:carbon_steel_ingot', 'technic:carbon_steel_ingot'},
}
@ -100,7 +144,7 @@ minetest.register_craft({
minetest.register_craft({
output = 'technic:hv_transformer',
recipe = {
{'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot'},
{isolation, 'technic:stainless_steel_ingot', isolation},
{'technic:copper_coil', 'technic:stainless_steel_ingot', 'technic:copper_coil'},
{'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot'},
}
@ -109,9 +153,9 @@ minetest.register_craft({
minetest.register_craft({
output = 'technic:control_logic_unit',
recipe = {
{'', 'default:gold_ingot', ''},
{'', 'technic:fine_gold_wire', ''},
{'default:copper_ingot', 'technic:silicon_wafer', 'default:copper_ingot'},
{'', 'default:copper_ingot', ''},
{'', 'technic:chromium_ingot', ''},
}
})
@ -120,7 +164,7 @@ minetest.register_craft({
recipe = {
{'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot'},
{'default:bronze_ingot', 'default:bronze_ingot', 'default:bronze_ingot'},
{'moreores:tin_ingot', 'moreores:tin_ingot', 'moreores:tin_ingot'},
{'default:tin_ingot', 'default:tin_ingot', 'default:tin_ingot'},
}
})
@ -131,44 +175,24 @@ minetest.register_craft({
}
})
-- Remove some recipes
minetest.register_craftitem("technic:nothing", {
description = "",
inventory_image = "blank.png",
minetest.register_craft({
output = "technic:machine_casing",
recipe = {
{ "technic:cast_iron_ingot", "technic:cast_iron_ingot", "technic:cast_iron_ingot" },
{ "technic:cast_iron_ingot", "technic:brass_ingot", "technic:cast_iron_ingot" },
{ "technic:cast_iron_ingot", "technic:cast_iron_ingot", "technic:cast_iron_ingot" },
},
})
if minetest.register_craft_predict then
minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv)
if itemstack:get_name() == "technic:nothing" then
return ItemStack("")
end
end)
end
-- Bronze
minetest.register_craft({
output = "default:dirt 2",
type = "shapeless",
output = "technic:nothing",
recipe = {"default:copper_ingot", "default:steel_ingot"}
})
-- Accelerator tube
minetest.register_craft({
output = "technic:nothing",
replacements = {{"bucket:bucket_water","bucket:bucket_empty"}},
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "default:mese_crystal_fragment", "default:steel_ingot", "default:mese_crystal_fragment" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
"technic:stone_dust",
"group:leaves",
"bucket:bucket_water",
"group:sand",
},
})
-- Teleport tube
minetest.register_craft({
output = "technic:nothing",
recipe = {
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" },
{ "default:desert_stone", "default:mese_block", "default:desert_stone" },
{ "homedecor:plastic_sheeting", "homedecor:plastic_sheeting", "homedecor:plastic_sheeting" }
},
})

View File

@ -1,7 +1,12 @@
default
moreores
pipeworks
mesecons
technic_worldgen
bucket?
screwdriver?
mesecons?
mesecons_mvps?
digilines?
digiline_remote?
intllib?
unified_inventory?
vector_extras?

133
technic/doc/api.md Normal file
View File

@ -0,0 +1,133 @@
This file is fairly incomplete. Help is welcome.
Tiers
-----
The tier is a string, currently `"LV"`, `"MV"` and `"HV"` are supported.
Network
-------
The network is the cable with the connected machine nodes. Currently the
switching station handles the network activity.
Helper functions
----------------
* `technic.EU_string(num)`
* Converts num to a human-readable string (see pretty_num)
and adds the `EU` unit
* Use this function when showing players energy values
* `technic.pretty_num(num)`
* Converts the number `num` to a human-readable string with SI prefixes
* `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.get_or_load_node(pos)`
* 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)`
* If the `wear_represents` field in the item's nodedef is
`"technic_RE_charge"`, this function does nothing.
* `technic.refill_RE_charge(itemstack)`
* This function fully recharges an RE chargeable item.
* If `technic.power_tools[itemstack:get_name()]` is `nil` (or `false`), this
function does nothing, else that value is the maximum charge.
* The itemstack metadata is changed to contain the charge.
* `technic.is_tier_cable(nodename, tier)`
* Tells whether the node `nodename` is the cable of the tier `tier`.
* `technic.get_cable_tier(nodename)`
* Returns the tier of the cable `nodename` or `nil`.
* `technic.trace_node_ray(pos, dir, range)`
* Returns an iteration function (usable in the for loop) to iterate over the
node positions along the specified ray.
* The returned positions will not include the starting position `pos`.
* `technic.trace_node_ray_fat(pos, dir, range)`
* Like `technic.trace_node_ray` but includes extra positions near the ray.
* 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`
### Specific machines
* `technic.register_solar_array(data)`
* data is a table
Used itemdef fields
-------------------
* groups:
* `technic_<ltier> = 1` ltier is a tier in small letters; this group makes
the node connect to the cable(s) of the right tier.
* `technic_machine = 1` Currently used for
* `connect_sides`
* In addition to the default use (see lua_api.txt), this tells where the
machine can be connected.
#
#
* `technic_run(pos, node)`
* This function is currently used to update the node.
Modders have to manually change the information about supply etc. in the
node metadata.
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
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
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
The reason the LV|MV|HV type is prepended to meta data is because some machine
could require several supplies to work.
This way the supplies are separated per network.

View File

@ -1,20 +1,71 @@
minetest.swap_node = minetest.swap_node or function(pos, node)
local oldmeta = minetest.get_meta(pos):to_table()
minetest.set_node(pos, node)
minetest.get_meta(pos):from_table(oldmeta)
local constant_digit_count = technic.config:get("constant_digit_count")
-- converts a number to a readable string with SI prefix, e.g. 10000 → "10 k",
-- 15 → "15 ", 0.1501 → "150.1 m"
-- a non-breaking space (U+a0) instead of a usual one is put after number
-- The precision is 4 digits
local prefixes = {[-8] = "y", [-7] = "z", [-6] = "a", [-5] = "f", [-4] = "p",
[-3] = "n", [-2] = "µ", [-1] = "m", [0] = "", [1] = "k", [2] = "M",
[3] = "G", [4] = "T", [5] = "P", [6] = "E", [7] = "Z", [8] = "Y"}
function technic.pretty_num(num)
-- the small number added is due to floating point inaccuracy
local b = math.floor(math.log10(math.abs(num)) +0.000001)
local pref_i
if b ~= 0 then
-- b is decremented by 1 to avoid a single digit with many decimals,
-- e.g. instead of 1.021 MEU, 1021 kEU is shown
pref_i = math.floor((b - 1) / 3)
else
-- as special case, avoid showing e.g. 1100 mEU instead of 1.1 EU
pref_i = 0
end
if not prefixes[pref_i] then
-- This happens for 0, nan, inf, very big values, etc.
if num == 0 then
-- handle 0 explicilty to avoid showing "-0"
if not constant_digit_count then
return "0 "
end
-- gives 0.000
return string.format("%.3f ", 0)
end
return string.format("%.4g ", num)
end
num = num * 10 ^ (-3 * pref_i)
if constant_digit_count then
local comma_digits_cnt = 3 - (b - 3 * pref_i)
return string.format("%." .. comma_digits_cnt .. "f %s",
num, prefixes[pref_i])
end
return string.format("%.4g %s", num, prefixes[pref_i])
end
-- Only changes name, keeps other params
-- some unittests
assert(technic.pretty_num(-0) == "0 ")
assert(technic.pretty_num(0) == "0 ")
assert(technic.pretty_num(1234) == "1234 ")
assert(technic.pretty_num(123456789) == "123.5 M")
-- used to display power values
function technic.EU_string(num)
return technic.pretty_num(num) .. "EU"
end
--- Same as minetest.swap_node, but only changes name
-- and doesn't re-set if already set.
function technic.swap_node(pos, name)
local node = minetest.get_node(pos)
if node.name ~= name then
node.name = name
minetest.swap_node(pos, node)
end
return node.name
end
-- Fully charge RE chargeable item.
--- Fully charge RE chargeable item.
-- Must be defined early to reference in item definitions.
function technic.refill_RE_charge(stack)
local max_charge = technic.power_tools[stack:get_name()]
@ -26,20 +77,148 @@ function technic.refill_RE_charge(stack)
return stack
end
--------------------------------------------------------------------------------
local function resolve_name(function_name)
local a = _G
for key in string.gmatch(function_name, "([^%.]+)(%.?)") do
if a[key] then
a = a[key]
else
return nil
end
end
return a
-- If the node is loaded, returns it. If it isn't loaded, load it and return nil.
function technic.get_or_load_node(pos)
local node = minetest.get_node_or_nil(pos)
if node then return node end
local vm = VoxelManip()
local MinEdge, MaxEdge = vm:read_from_map(pos, pos)
return nil
end
function technic.function_exists(function_name)
return type(resolve_name(function_name)) == 'function'
technic.tube_inject_item = pipeworks.tube_inject_item or function(pos, start_pos, velocity, item)
local tubed = pipeworks.tube_item(vector.new(pos), item)
tubed:get_luaentity().start_pos = vector.new(start_pos)
tubed:setvelocity(velocity)
tubed:setacceleration(vector.new(0, 0, 0))
end
--------------------------------------------------------------------------------
--- Iterates over the node positions along the specified ray.
-- The returned positions will not include the starting position.
function technic.trace_node_ray(pos, dir, range)
local x_step = dir.x > 0 and 1 or -1
local y_step = dir.y > 0 and 1 or -1
local z_step = dir.z > 0 and 1 or -1
local i = 1
return function(p)
-- Approximation of where we should be if we weren't rounding
-- to nodes. This moves forward a bit faster then we do.
-- A correction is done below.
local real_x = pos.x + (dir.x * i)
local real_y = pos.y + (dir.y * i)
local real_z = pos.z + (dir.z * i)
-- How far off we've gotten from where we should be.
local dx = math.abs(real_x - p.x)
local dy = math.abs(real_y - p.y)
local dz = math.abs(real_z - p.z)
-- If the real position moves ahead too fast, stop it so we
-- can catch up. If it gets too far ahead it will smooth
-- out our movement too much and we won't turn fast enough.
if dx + dy + dz < 2 then
i = i + 1
end
-- Step in whichever direction we're most off course in.
if dx > dy then
if dx > dz then
p.x = p.x + x_step
else
p.z = p.z + z_step
end
elseif dy > dz then
p.y = p.y + y_step
else
p.z = p.z + z_step
end
if vector.distance(pos, p) > range then
return nil
end
return p
end, vector.round(pos)
end
--- Like trace_node_ray, but includes extra positions close to the ray.
function technic.trace_node_ray_fat(pos, dir, range)
local x_step = dir.x > 0 and 1 or -1
local y_step = dir.y > 0 and 1 or -1
local z_step = dir.z > 0 and 1 or -1
local next_poses = {}
local i = 1
return function(p)
local ni, np = next(next_poses)
if np then
next_poses[ni] = nil
return np
end
-- Approximation of where we should be if we weren't rounding
-- to nodes. This moves forward a bit faster then we do.
-- A correction is done below.
local real_x = pos.x + (dir.x * i)
local real_y = pos.y + (dir.y * i)
local real_z = pos.z + (dir.z * i)
-- How far off we've gotten from where we should be.
local dx = math.abs(real_x - p.x)
local dy = math.abs(real_y - p.y)
local dz = math.abs(real_z - p.z)
-- If the real position moves ahead too fast, stop it so we
-- can catch up. If it gets too far ahead it will smooth
-- out our movement too much and we won't turn fast enough.
if dx + dy + dz < 2 then
i = i + 1
end
-- Step in whichever direction we're most off course in.
local sx, sy, sz -- Whether we've already stepped along each axis
if dx > dy then
if dx > dz then
sx = true
p.x = p.x + x_step
else
sz = true
p.z = p.z + z_step
end
elseif dy > dz then
sy = true
p.y = p.y + y_step
else
sz = true
p.z = p.z + z_step
end
if vector.distance(pos, p) > range then
return nil
end
-- Add other positions that we're significantly off on.
-- We can just use fixed integer keys here because the
-- table will be completely cleared before we reach this
-- code block again.
local dlen = math.sqrt(dx*dx + dy*dy + dz*dz)
-- Normalized axis deltas
local dxn, dyn, dzn = dx / dlen, dy / dlen, dz / dlen
if not sx and dxn > 0.5 then
next_poses[1] = vector.new(p.x + x_step, p.y, p.z)
end
if not sy and dyn > 0.5 then
next_poses[2] = vector.new(p.x, p.y + y_step, p.z)
end
if not sz and dzn > 0.5 then
next_poses[3] = vector.new(p.x, p.y, p.z + z_step)
end
return p
end, vector.round(pos)
end

View File

@ -2,17 +2,21 @@
-- namespace: technic
-- (c) 2012-2013 by RealBadAngel <mk@realbadangel.pl>
technic = {}
local load_start = os.clock()
technic = rawget(_G, "technic") or {}
technic.creative_mode = minetest.settings:get_bool("creative_mode")
local modpath = minetest.get_modpath("technic")
technic.modpath = modpath
-- Boilerplate to support intllib
if intllib then
if rawget(_G, "intllib") then
technic.getter = intllib.Getter()
else
technic.getter = function(s) return s 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"")else return"@"..o..n..c end end) end
end
local S = technic.getter
@ -31,6 +35,9 @@ dofile(modpath.."/crafts.lua")
-- Register functions
dofile(modpath.."/register.lua")
-- Radiation
dofile(modpath.."/radiation.lua")
-- Machines
dofile(modpath.."/machines/init.lua")
@ -40,7 +47,7 @@ dofile(modpath.."/tools/init.lua")
-- Aliases for legacy node/item names
dofile(modpath.."/legacy.lua")
if minetest.setting_get("log_mod") then
if minetest.settings:get_bool("log_mods") then
print(S("[Technic] Loaded in %f seconds"):format(os.clock() - load_start))
end

View File

@ -11,11 +11,6 @@ minetest.register_craftitem( "technic:doped_silicon_wafer", {
inventory_image = "technic_doped_silicon_wafer.png",
})
minetest.register_craftitem("technic:enriched_uranium", {
description = S("Enriched Uranium"),
inventory_image = "technic_enriched_uranium.png",
})
minetest.register_craftitem("technic:uranium_fuel", {
description = S("Uranium Fuel"),
inventory_image = "technic_uranium_fuel.png",
@ -80,6 +75,16 @@ minetest.register_craftitem("technic:fine_copper_wire", {
inventory_image = "technic_fine_copper_wire.png",
})
minetest.register_craftitem("technic:fine_gold_wire", {
description = S("Fine Gold Wire"),
inventory_image = "technic_fine_gold_wire.png",
})
minetest.register_craftitem("technic:fine_silver_wire", {
description = S("Fine Silver Wire"),
inventory_image = "technic_fine_silver_wire.png",
})
minetest.register_craftitem("technic:copper_coil", {
description = S("Copper Coil"),
inventory_image = "technic_copper_coil.png",
@ -95,10 +100,6 @@ minetest.register_craftitem("technic:lv_transformer", {
inventory_image = "technic_lv_transformer.png",
})
minetest.register_craftitem("technic:lv_transformer", {
description = S("Low Voltage Transformer"),
inventory_image = "technic_lv_transformer.png",
})
minetest.register_craftitem("technic:mv_transformer", {
description = S("Medium Voltage Transformer"),
inventory_image = "technic_mv_transformer.png",
@ -144,3 +145,80 @@ minetest.register_craftitem("technic:carbon_cloth", {
inventory_image = "technic_carbon_cloth.png",
})
minetest.register_node("technic:machine_casing", {
description = S("Machine Casing"),
groups = {cracky=2},
sunlight_propagates = true,
paramtype = "light",
drawtype = "allfaces",
tiles = {"technic_machine_casing.png"},
sounds = default.node_sound_stone_defaults(),
})
for p = 0, 35 do
local nici = (p ~= 0 and p ~= 7 and p ~= 35) and 1 or nil
local psuffix = p == 7 and "" or p
local ingot = "technic:uranium"..psuffix.."_ingot"
local block = "technic:uranium"..psuffix.."_block"
local ov = p == 7 and minetest.override_item or nil;
(ov or minetest.register_craftitem)(ingot, {
description = string.format(S("%.1f%%-Fissile Uranium Ingot"), p/10),
inventory_image = "technic_uranium_ingot.png",
groups = {uranium_ingot=1, not_in_creative_inventory=nici},
});
-- Note on radioactivity of blocks:
-- Source: <http://www.wise-uranium.org/rup.html>
-- The baseline radioactivity of an isotope is not especially
-- correlated with whether it's fissile (i.e., suitable as
-- reactor fuel). Natural uranium consists mainly of fissile
-- U-235 and non-fissile U-238, and both U-235 and U-238 are
-- significantly radioactive. U-235's massic activity is
-- about 80.0 MBq/kg, and U-238's is about 12.4 MBq/kg, which
-- superficially suggests that 3.5%-fissile uranium should have
-- only 1.19 times the activity of fully-depleted uranium.
-- But a third isotope affects the result hugely: U-234 has
-- massic activity of 231 GBq/kg. Natural uranium has massic
-- composition of 99.2837% U-238, 0.711% U-235, and 0.0053% U-234,
-- so its activity comes roughly 49% each from U-234 and U-238
-- and only 2% from U-235. During enrichment via centrifuge,
-- the U-234 fraction is concentrated along with the U-235, with
-- the U-234:U-235 ratio remaining close to its original value.
-- (Actually the U-234 gets separated from U-238 slightly more
-- than the U-235 is, so the U-234:U-235 ratio is slightly
-- higher in enriched uranium.) A typical massic composition
-- for 3.5%-fissile uranium is 96.47116% U-238, 3.5% U-235, and
-- 0.02884% U-234. This gives 3.5%-fissile uranium about 6.55
-- times the activity of fully-depleted uranium. The values we
-- compute here for the "radioactive" group value are based on
-- linear interpolation of activity along that scale, rooted at
-- a natural (0.7%-fissile) uranium block having the activity of
-- 9 uranium ore blocks (due to 9 ingots per block). The group
-- value is proportional to the square root of the activity, and
-- uranium ore has radioactive=1. This yields radioactive=1.0
-- for a fully-depleted uranium block and radioactive=2.6 for
-- a 3.5%-fissile uranium block.
local radioactivity = math.floor(math.sqrt((1+5.55*p/35) * 18 / (1+5.55*7/35)) + 0.5);
(ov or minetest.register_node)(block, {
description = string.format(S("%.1f%%-Fissile Uranium Block"), p/10),
tiles = {"technic_uranium_block.png"},
is_ground_content = true,
groups = {uranium_block=1, not_in_creative_inventory=nici,
cracky=1, level=2, radioactive=radioactivity},
sounds = default.node_sound_stone_defaults(),
});
if not ov then
minetest.register_craft({
output = block,
recipe = {
{ingot, ingot, ingot},
{ingot, ingot, ingot},
{ingot, ingot, ingot},
},
})
minetest.register_craft({
output = ingot.." 9",
recipe = {{block}},
})
end
end

View File

@ -22,16 +22,20 @@ technic.legacy_nodenames = {
["technic:compressor"] = "technic:lv_compressor",
["technic:compressor_active"] = "technic:lv_compressor_active",
["technic:hv_battery_box"] = "technic:hv_battery_box0",
["technic:hv_cable"] = "technic:hv_cable0",
["technic:lv_cable"] = "technic:lv_cable0",
["technic:mv_cable"] = "technic:mv_cable0",
["technic:mv_battery_box"] = "technic:mv_battery_box0",
["technic:generator"] = "technic:lv_generator",
["technic:generator_active"] = "technic:lv_generator_active",
["technic:iron_dust"] = "technic:wrought_iron_dust",
["technic:enriched_uranium"] = "technic:uranium35_ingot",
}
for old, new in pairs(technic.legacy_nodenames) do
minetest.register_alias(old, new)
end
for i = 0, 64 do
minetest.register_alias("technic:hv_cable"..i, "technic:hv_cable")
minetest.register_alias("technic:mv_cable"..i, "technic:mv_cable")
minetest.register_alias("technic:lv_cable"..i, "technic:lv_cable")
end

View File

@ -29,11 +29,14 @@ Graphite = Graphit
Carbon Cloth = Kohlefasergewebe
Raw Latex = Rohlatex
Rubber Fiber = Gummifaser
%.1f%%-Fissile Uranium Ingot =
%.1f%%-Fissile Uranium Block =
## Machine misc
Machine cannot be removed because it is not empty = Die Maschine kann nicht entfernt werden, weil sie noch nicht leer ist.
Inventory move disallowed due to protection = Das Inventar ist geschuetzt, Zugriff verweigert.
# $1: Machine name (Includes tier)
@1 Active (@2 EU) = @1 ist eingeschaltet (@2 EU)
%s Active = %s ist eingeschaltet
%s Disabled = %s ist ausgeschaltet
%s Enabled =
@ -50,9 +53,14 @@ Upgrade Slots = Verbesserungsfaecher
In: = Rein:
Out: = Raus:
Slot %d = Fach %d
Mode: %s = Methode: %s
single items = Einzelstuecke
whole stacks = Ganzer Stapel
Itemwise = Einzelstuecke
Stackwise = Ganzer Stapel
Owner: =
Unlocked =
Locked =
Radius: =
Enabled =
Disabled =
## Machine names
# $1: Tier
@ -75,7 +83,7 @@ Hydro %s Generator = %s Wassermuehle
Nuclear %s Generator Core = %s Reaktorkern
Small Solar %s Generator = %s Solarmodul
Wind %s Generator = %s Windmuehle
Injector = Injektor
Self-Contained Injector = Selbstversorger-Injektor
Constructor Mk%d = Konstruktor Modell %d
Frame = Rahmen
Frame Motor = Rahmenmotor
@ -91,6 +99,7 @@ Fuel-Fired Furnace = Kohle-Ofen
Wind Mill Frame = Windmuehlengeruest
Forcefield = Kraftfeld
Nuclear Reactor Rod Compartment = Brennstabfaecher
Administrative World Anchor =
## Machine-specific
# $1: Pruduced EU
@ -98,13 +107,19 @@ Charge = Aufladen
Discharge = Entladen
Power level = Energiestufe
# $1: Tier $2: current_charge $3: max_charge
%s Battery Box: %d/%d = %s Batteriebox: %d/%d
@1 Battery Box: @2/@3 = @1 Batteriebox: @2/@3
# $1: Machine name $2: Supply $3: Demand
%s. Supply: %d Demand: %d = %s. Versorgung: %d Bedarf: %d
@1. Supply: @2 Demand: @3 = @1. Versorgung: @2 Bedarf: @3
Production at %d%% = Produktion bei %d%%
Choose Milling Program: = Waehle ein Fraesprogramm:
Slim Elements half / normal height: = Schmale Elemente von halber / normaler Hoehe:
Current track %s = Aktueller Titel %s
Stopped =
Keeping %d/%d map blocks loaded =
Digging not started =
Digging finished =
Digging %d m above machine =
Digging %d m below machine =
## CNC
Cylinder = Zylinder
@ -162,6 +177,7 @@ Talinite = Talinite
Tin = Zinn
Wrought Iron = Schmiedeeisen
Zinc = Zink
%.1f%%-Fissile Uranium =
## Tools
RE Battery = Akkubatterie

View File

@ -29,11 +29,14 @@ Graphite = Grafito
Carbon Cloth = Tela de Carbon
Raw Latex = Latex Crudo
Rubber Fiber = Fibra de Hule
%.1f%%-Fissile Uranium Ingot =
%.1f%%-Fissile Uranium Block =
## Machine misc
Machine cannot be removed because it is not empty = La maquina no puede removerse porque no esta vacia
Inventory move disallowed due to protection =
# $1: Machine name (Includes tier)
@1 Active (@2 EU) = @1 Activo (@2 EU)
%s Active = %s Activo
%s Enabled =
%s Idle = %s Quieto
@ -46,6 +49,14 @@ Inventory move disallowed due to protection =
%s Improperly Placed = %s No Colocado Apropiadamente
Range = Alcance
Enable/Disable = Habilitar/Deshabilitar
Itemwise =
Stackwise =
Owner: =
Unlocked =
Locked =
Radius: =
Enabled =
Disabled =
## Machine names
# $1: Tier
@ -68,7 +79,7 @@ Hydro %s Generator = Molino de Agua %s
Nuclear %s Generator Core = Nucleo de Reactor Nuclear %s
Small Solar %s Generator = Panel Solar %s
Wind %s Generator = Molino de Viento %s
Injector =
Self-Contained Injector =
Constructor Mk%d =
Frame =
Frame Motor =
@ -84,6 +95,7 @@ Fuel-Fired Furnace = Horno a Carbon
Forcefield = Campo de Fuerza
Nuclear Reactor Rod Compartment = Compartimiento para Vara de Reactor Nuclear
Wind Mill Frame = Armazon de Molino de Viento
Administrative World Anchor =
## Machine-specific
# $1: Pruduced EU
@ -91,11 +103,17 @@ Charge = Cargar
Discharge = Descargar
Power level = Nivel de Poder
# $1: Tier $2: current_charge $3: max_charge
%s Battery Box: %d/%d = Caja de Bateria %s: %d/%d
@1 Battery Box: @2/@3 = Caja de Bateria @1: @2/@3
# $1: Machine name $2: Supply $3: Demand
%s. Supply: %d Demand: %d = %s. Alimentacion: %d Demanda: %d
@1. Supply: @2 Demand: @3 = @1. Alimentacion: @2 Demanda: @3
# $1: Production percent
Production at %d%% = Produccion en %d%%
Stopped =
Keeping %d/%d map blocks loaded =
Digging not started =
Digging finished =
Digging %d m above machine =
Digging %d m below machine =
## CNC Machine
Element Edge = Elemento Borde
@ -152,6 +170,7 @@ Talinite = Talinita
Tin = Estanio
Wrought Iron = Hierro Forjado
Zinc = Zinc
%.1f%%-Fissile Uranium =
## Tools
RE Battery =

View File

@ -26,14 +26,17 @@ Graphite = Lastra in graffite
Carbon Cloth = Fibra di carbonio
Raw Latex = Latex grezzo
Rubber Fiber = Fibra di gomma
%.1f%%-Fissile Uranium Ingot = %.1f%%-Lingotto di uranio fissile
%.1f%%-Fissile Uranium Block = %.1f%%-Blocco di uranio fissile
## Machine misc
Machine cannot be removed because it is not empty = La macchina non può essere rimossa perchè non è vuota
Inventory move disallowed due to protection = Impossibile muovere l'inventario a causa della protezione
# $1: Machine name (Includes tier)
@1 Active (@2 EU) = @1 Attivo (@2 EU)
%s Active = %s Attivo
%s Disabled = %s Disabilitato
%s Enabled =
%s Enabled = %s Abilitato
%s Idle = %s Inattivo
%s Improperly Placed = %s Piazzato impropiamente
%s Unpowered = %s Non alimentato
@ -43,13 +46,18 @@ Inventory move disallowed due to protection = Impossibile muovere l'inventario a
%s Finished = %s Finito
Enable/Disable = Abilita/Disabilita
Range = Raggio
Upgrade Slots =
Upgrade Slots = Alloggi di aggiornamento
In: = Ingresso:
Out: = Uscita:
Slot %d =
Mode: %s = Modalità: %s
single items = Singolo elemento
whole stacks = pila completa
Slot %d = Alloggio %d
Itemwise = Singolo elemento
Stackwise = pila completa
Owner: = Proprietario:
Unlocked = Non chiuso a chiave
Locked = Chiuso a chiave
Radius: = Raggio:
Enabled = Abilitato
Disabled = Disabilitato
## Machine names
# $1: Tier
@ -72,14 +80,14 @@ Hydro %s Generator = Turbina Elettrica %s
Nuclear %s Generator Core = Reattore nucleare %s
Small Solar %s Generator = %s Pannello solare
Wind %s Generator = %s Generatore eolico
Injector = Ignettore
Self-Contained Injector = Ignettore
Constructor Mk%d = Costruttore Mk%d
Frame = Cornice
Frame Motor = Cornice del motore
Template =
Template (replacing) = Template (rimpiazzato)
Template Motor =
Template Tool =
Template = Sagoma
Template (replacing) = Sagoma (di rimpiazzo)
Template Motor = Motore per sagome
Template Tool = Strumento per sagome
Battery Box = Box batterie
Supply Converter = Trasformatore
Switching Station = Stazione di controllo
@ -88,6 +96,7 @@ Fuel-Fired Furnace = Fornace a carbone
Wind Mill Frame = Pala eolica
Forcefield = Campo di forza
Nuclear Reactor Rod Compartment = Compartimento combustibile nucleare
Administrative World Anchor = Ancora-mondo amministrativa
## Machine-specific
# $1: Pruduced EU
@ -95,13 +104,19 @@ Charge = Carica
Discharge = Scarica
Power level = Livello di potenza
# $1: Tier $2: current_charge $3: max_charge
%s Battery Box: %d/%d = %s Box Batterie: %d/%d
@1 Battery Box: @2/@3 = @1 Box Batterie: @2/@3
# $1: Machine name $2: Supply $3: Demand
%s. Supply: %d Demand: %d = %s. Prodotto: %d Consumato: %d
@1. Supply: @2 Demand: @3 = @1. Prodotto: @2 Consumato: @3
Production at %d%% = Produzione a %d%%
Choose Milling Program: = Scegliere un programma di Fresatura
Slim Elements half / normal height: = Metà elementi sottili / altezza normale:
Current track %s = Traccia corrente %s
Stopped = Fermato
Keeping %d/%d map blocks loaded = Mantenimento di %d/%d blocchi mappa caricati
Digging not started = Scavo non iniziato
Digging finished = Scavo finito
Digging %d m above machine = Scavo di %d m sopra la macchina
Digging %d m below machine = Scavo di %d m sotto la macchina
## CNC
Cylinder = Cilindro
@ -159,9 +174,10 @@ Talinite = Talinite
Tin = Stagno
Wrought Iron = Ferro Battuto
Zinc = Zinco
%.1f%%-Fissile Uranium = %.1f%%-Uranio fissile
## Tools
RE Battery =
RE Battery = Batteria RE
Water Can = Serbatoio d'acqua
Lava Can = Serbatoio di lava
Chainsaw = Motosega

View File

@ -29,11 +29,14 @@ Graphite =
Carbon Cloth =
Raw Latex =
Rubber Fiber =
%.1f%%-Fissile Uranium Ingot =
%.1f%%-Fissile Uranium Block =
## Machine misc
Machine cannot be removed because it is not empty =
Inventory move disallowed due to protection =
# $1: Machine name (Includes tier)
@1 Active (@2 EU) =
%s Active =
%s Disabled =
%s Enabled =
@ -43,6 +46,7 @@ Inventory move disallowed due to protection =
%s Unpowered =
%s Out Of Fuel =
%s Has Bad Cabling =
%s (Slave) =
%s Has No Network =
%s Finished =
Enable/Disable =
@ -51,16 +55,24 @@ Upgrade Slots =
In: =
Out: =
Slot %d =
Mode: %s =
single items =
whole stacks =
Itemwise =
Stackwise =
Ignoring Mesecon Signal =
Controlled by Mesecon Signal =
Owner: =
Unlocked =
Locked =
Radius: =
Enabled =
Disabled =
## Machine names
# $1: Tier
%s Alloy Furnace =
%s Battery Box =
%s Battery Box =
%s Cable =
%s CNC Machine =
%s Centrifuge =
%s Compressor =
%s Extractor =
%s Forcefield Emitter =
@ -76,7 +88,7 @@ Hydro %s Generator =
Nuclear %s Generator Core =
Small Solar %s Generator =
Wind %s Generator =
Injector =
Self-Contained Injector =
Constructor Mk%d =
Frame =
Frame Motor =
@ -92,6 +104,7 @@ Fuel-Fired Furnace =
Wind Mill Frame =
Forcefield =
Nuclear Reactor Rod Compartment =
Administrative World Anchor =
## Machine-specific
# $1: Pruduced EU
@ -99,13 +112,20 @@ Charge =
Discharge =
Power level =
# $1: Tier $2: current_charge $3: max_charge
%s Battery Box: %d/%d =
@1 Battery Box: @2/@3 =
# $1: Machine name $2: Supply $3: Demand
%s. Supply: %d Demand: %d =
@1. Supply: @2 Demand: @3 =
Production at %d%% =
Choose Milling Program: =
Slim Elements half / normal height: =
Current track %s =
Stopped =
Keeping %d/%d map blocks loaded =
Digging not started =
Digging finished =
Digging %d m above machine =
Digging %d m below machine =
@1 (@2 @3 -> @4 @5) =
## CNC
Cylinder =
@ -163,6 +183,7 @@ Talinite =
Tin =
Wrought Iron =
Zinc =
%.1f%%-Fissile Uranium =
## Tools
RE Battery =
@ -187,3 +208,4 @@ Alloy cooking =
Grinding =
Compressing =
Extracting =
Separating =

View File

@ -1,10 +1,11 @@
-- HV battery box
minetest.register_craft({
output = 'technic:hv_battery_box0',
recipe = {
{'technic:mv_battery_box0', 'technic:mv_battery_box0', 'technic:mv_battery_box0'},
{'technic:mv_battery_box0', 'technic:hv_transformer', 'technic:mv_battery_box0'},
{'', 'technic:hv_cable0', ''},
{'', 'technic:hv_cable', ''},
}
})

View File

@ -1,10 +1,10 @@
minetest.register_craft({
output = 'technic:hv_cable0 3',
output = 'technic:hv_cable 3',
recipe = {
{'technic:rubber', 'technic:rubber', 'technic:rubber'},
{'technic:mv_cable0', 'technic:mv_cable0', 'technic:mv_cable0'},
{'technic:rubber', 'technic:rubber', 'technic:rubber'},
{'homedecor:plastic_sheeting', 'homedecor:plastic_sheeting', 'homedecor:plastic_sheeting'},
{'technic:mv_cable', 'technic:mv_cable', 'technic:mv_cable'},
{'homedecor:plastic_sheeting', 'homedecor:plastic_sheeting', 'homedecor:plastic_sheeting'},
}
})

View File

@ -1,26 +1,40 @@
-- Forcefield mod by ShadowNinja
-- Modified by kpoppel
--- Forcefield generator.
-- @author ShadowNinja
--
-- Forcefields are powerful barriers but they consume huge amounts of power.
-- Forcefield Generator is a HV machine.
-- The forcefield Generator is an HV machine.
-- How expensive is the generator?
-- Leaves room for upgrades lowering the power drain?
local digilines_path = minetest.get_modpath("digilines")
local forcefield_power_drain = 10
local forcefield_step_interval = 1
local S = technic.getter
local cable_entry = "^technic_cable_connection_overlay.png"
minetest.register_craft({
output = 'technic:forcefield_emitter_off',
output = "technic:forcefield_emitter_off",
recipe = {
{'default:mese', 'technic:deployer_off', 'default:mese' },
{'technic:deployer_off', 'technic:motor', 'technic:deployer_off'},
{'default:mese', 'technic:deployer_off', 'default:mese' },
{"default:mese", "technic:motor", "default:mese" },
{"technic:deployer_off", "technic:machine_casing", "technic:deployer_off"},
{"default:mese", "technic:hv_cable", "default:mese" },
}
})
local replaceable_cids = {}
minetest.after(0, function()
for name, ndef in pairs(minetest.registered_nodes) do
if ndef.buildable_to == true and name ~= "ignore" then
replaceable_cids[minetest.get_content_id(name)] = true
end
end
end)
-- Idea: Let forcefields have different colors by upgrade slot.
-- Idea: Let forcefields add up by detecting if one hits another.
-- ___ __
@ -28,26 +42,39 @@ minetest.register_craft({
-- | |
-- \___/\___/
local function update_forcefield(pos, range, active)
local function update_forcefield(pos, meta, active, first)
local shape = meta:get_int("shape")
local range = meta:get_int("range")
local vm = VoxelManip()
local p1 = {x = pos.x-range, y = pos.y-range, z = pos.z-range}
local p2 = {x = pos.x+range, y = pos.y+range, z = pos.z+range}
local MinEdge, MaxEdge = vm:read_from_map(p1, p2)
local MinEdge, MaxEdge = vm:read_from_map(vector.subtract(pos, range),
vector.add(pos, range))
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
local data = vm:get_data()
local c_air = minetest.get_content_id("air")
local c_air = minetest.get_content_id("air")
local c_field = minetest.get_content_id("technic:forcefield")
for z=-range, range do
for y=-range, range do
local vi = area:index(pos.x+(-range), pos.y+y, pos.z+z)
for x=-range, range do
if x*x+y*y+z*z <= range * range + range and
x*x+y*y+z*z >= (range-1) * (range-1) + (range-1) then
if active and data[vi] == c_air then
for z = -range, range do
for y = -range, range do
local vi = area:index(pos.x + (-range), pos.y + y, pos.z + z)
for x = -range, range do
local relevant
if shape == 0 then
local squared = x * x + y * y + z * z
relevant =
squared <= range * range + range and
squared >= (range - 1) * (range - 1) + (range - 1)
else
relevant =
x == -range or x == range or
y == -range or y == range or
z == -range or z == range
end
if relevant then
local cid = data[vi]
if active and replaceable_cids[cid] then
data[vi] = c_field
elseif not active and data[vi] == c_field then
elseif not active and cid == c_field then
data[vi] = c_air
end
end
@ -59,54 +86,214 @@ local function update_forcefield(pos, range, active)
vm:set_data(data)
vm:update_liquids()
vm:write_to_map()
vm:update_map()
-- update_map is very slow, but if we don't call it we'll
-- get phantom blocks on the client.
if not active or first then
vm:update_map()
end
end
local function set_forcefield_formspec(meta)
local formspec = "size[5,1.5]"..
"field[2,0.5;2,1;range;"..S("Range")..";"..meta:get_int("range").."]"
if meta:get_int("enabled") == 0 then
formspec = formspec.."button[0,1;5,1;enable;"..S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
local formspec
if digilines_path then
formspec = "size[5,3.25]"..
"field[0.3,3;5,1;channel;Digiline Channel;"..meta:get_string("channel").."]"
else
formspec = formspec.."button[0,1;5,1;disable;"..S("%s Enabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
formspec = "size[5,2.25]"
end
formspec = formspec..
"field[0.3,0.5;2,1;range;"..S("Range")..";"..meta:get_int("range").."]"
-- The names for these toggle buttons are explicit about which
-- state they'll switch to, so that multiple presses (arising
-- from the ambiguity between lag and a missed press) only make
-- the single change that the user expects.
if meta:get_int("shape") == 0 then
formspec = formspec.."button[3,0.2;2,1;shape1;"..S("Sphere").."]"
else
formspec = formspec.."button[3,0.2;2,1;shape0;"..S("Cube").."]"
end
if meta:get_int("mesecon_mode") == 0 then
formspec = formspec.."button[0,1;5,1;mesecon_mode_1;"..S("Ignoring Mesecon Signal").."]"
else
formspec = formspec.."button[0,1;5,1;mesecon_mode_0;"..S("Controlled by Mesecon Signal").."]"
end
if meta:get_int("enabled") == 0 then
formspec = formspec.."button[0,1.75;5,1;enable;"..S("%s Disabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
else
formspec = formspec.."button[0,1.75;5,1;disable;"..S("%s Enabled"):format(S("%s Forcefield Emitter"):format("HV")).."]"
end
meta:set_string("formspec", formspec)
end
local forcefield_receive_fields = function(pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
local range = nil
if fields.range then
local range = tonumber(fields.range) or 0
range = tonumber(fields.range) or 0
-- Smallest field is 5. Anything less is asking for trouble.
-- Largest is 20. It is a matter of pratical node handling.
-- At the maximim range updating the forcefield takes about 0.2s
range = math.max(range, 5)
range = math.min(range, 20)
if meta:get_int("range") ~= range then
update_forcefield(pos, meta:get_int("range"), false)
meta:set_int("range", range)
end
if range == meta:get_int("range") then range = nil end
end
if fields.enable then meta:set_int("enabled", 1) end
if fields.shape0 or fields.shape1 or range then
update_forcefield(pos, meta, false)
end
if range then meta:set_int("range", range) end
if fields.channel then meta:set_string("channel", fields.channel) end
if fields.shape0 then meta:set_int("shape", 0) end
if fields.shape1 then meta:set_int("shape", 1) end
if fields.enable then meta:set_int("enabled", 1) end
if fields.disable then meta:set_int("enabled", 0) end
if fields.mesecon_mode_0 then meta:set_int("mesecon_mode", 0) end
if fields.mesecon_mode_1 then meta:set_int("mesecon_mode", 1) end
set_forcefield_formspec(meta)
end
local mesecons = {
effector = {
action_on = function(pos, node)
minetest.get_meta(pos):set_int("enabled", 0)
minetest.get_meta(pos):set_int("mesecon_effect", 1)
end,
action_off = function(pos, node)
minetest.get_meta(pos):set_int("enabled", 1)
minetest.get_meta(pos):set_int("mesecon_effect", 0)
end
}
}
local digiline_def = {
receptor = {action = function() end},
effector = {
action = function(pos, node, channel, msg)
local meta = minetest.get_meta(pos)
if channel ~= meta:get_string("channel") then
return
end
local msgt = type(msg)
if msgt == "string" then
local smsg = msg:lower()
msg = {}
if smsg == "get" then
msg.command = "get"
elseif smsg == "off" then
msg.command = "off"
elseif smsg == "on" then
msg.command = "on"
elseif smsg == "toggle" then
msg.command = "toggle"
elseif smsg:sub(1, 5) == "range" then
msg.command = "range"
msg.value = tonumber(smsg:sub(7))
elseif smsg:sub(1, 5) == "shape" then
msg.command = "shape"
msg.value = smsg:sub(7):lower()
msg.value = tonumber(msg.value) or msg.value
end
elseif msgt ~= "table" then
return
end
if msg.command == "get" then
digilines.receptor_send(pos, digilines.rules.default, channel, {
enabled = meta:get_int("enabled"),
range = meta:get_int("range"),
shape = meta:get_int("shape")
})
return
elseif msg.command == "off" then
meta:set_int("enabled", 0)
elseif msg.command == "on" then
meta:set_int("enabled", 1)
elseif msg.command == "toggle" then
local onn = meta:get_int("enabled")
onn = 1-onn -- Mirror onn with pivot 0.5, so switch between 1 and 0.
meta:set_int("enabled", onn)
elseif msg.command == "range" then
if type(msg.value) ~= "number" then
return
end
msg.value = math.max(msg.value, 5)
msg.value = math.min(msg.value, 20)
update_forcefield(pos, meta, false)
meta:set_int("range", msg.value)
elseif msg.command == "shape" then
local valuet = type(msg.value)
if valuet == "string" then
if msg.value == "sphere" then
msg.value = 0
elseif msg.value == "cube" then
msg.value = 1
end
elseif valuet ~= "number" then
return
end
if not msg.value then
return
end
update_forcefield(pos, meta, false)
meta:set_int("shape", msg.value)
else
return
end
set_forcefield_formspec(meta)
end
},
}
local function run(pos, node)
local meta = minetest.get_meta(pos)
local eu_input = meta:get_int("HV_EU_input")
local enabled = meta:get_int("enabled") ~= 0 and
(meta:get_int("mesecon_mode") == 0 or meta:get_int("mesecon_effect") ~= 0)
local machine_name = S("%s Forcefield Emitter"):format("HV")
local range = meta:get_int("range")
local power_requirement
if meta:get_int("shape") == 0 then
power_requirement = math.floor(4 * math.pi * range * range)
else
power_requirement = 24 * range * range
end
power_requirement = power_requirement * forcefield_power_drain
if not enabled then
if node.name == "technic:forcefield_emitter_on" then
update_forcefield(pos, meta, false)
technic.swap_node(pos, "technic:forcefield_emitter_off")
meta:set_string("infotext", S("%s Disabled"):format(machine_name))
end
meta:set_int("HV_EU_demand", 0)
return
end
meta:set_int("HV_EU_demand", power_requirement)
if eu_input < power_requirement then
meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
if node.name == "technic:forcefield_emitter_on" then
update_forcefield(pos, meta, false)
technic.swap_node(pos, "technic:forcefield_emitter_off")
end
elseif eu_input >= power_requirement then
local first = false
if node.name == "technic:forcefield_emitter_off" then
first = true
technic.swap_node(pos, "technic:forcefield_emitter_on")
meta:set_string("infotext", S("%s Active"):format(machine_name))
end
update_forcefield(pos, meta, true, first)
end
end
minetest.register_node("technic:forcefield_emitter_off", {
description = S("%s Forcefield Emitter"):format("HV"),
tiles = {"technic_forcefield_emitter_off.png"},
groups = {cracky = 1},
tiles = {
"technic_forcefield_emitter_off.png",
"technic_machine_bottom.png"..cable_entry,
"technic_forcefield_emitter_off.png",
"technic_forcefield_emitter_off.png",
"technic_forcefield_emitter_off.png",
"technic_forcefield_emitter_off.png"
},
groups = {cracky = 1, technic_machine = 1, technic_hv = 1},
on_receive_fields = forcefield_receive_fields,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
@ -114,37 +301,59 @@ minetest.register_node("technic:forcefield_emitter_off", {
meta:set_int("HV_EU_demand", 0)
meta:set_int("range", 10)
meta:set_int("enabled", 0)
meta:set_int("mesecon_mode", 0)
meta:set_int("mesecon_effect", 0)
if digilines_path then
meta:set_string("channel", "forcefield"..minetest.pos_to_string(pos))
end
meta:set_string("infotext", S("%s Forcefield Emitter"):format("HV"))
set_forcefield_formspec(meta)
end,
mesecons = mesecons
mesecons = mesecons,
digiline = digiline_def,
technic_run = run,
})
minetest.register_node("technic:forcefield_emitter_on", {
description = S("%s Forcefield Emitter"):format("HV"),
tiles = {"technic_forcefield_emitter_on.png"},
groups = {cracky = 1, not_in_creative_inventory=1},
tiles = {
"technic_forcefield_emitter_on.png",
"technic_machine_bottom.png"..cable_entry,
"technic_forcefield_emitter_on.png",
"technic_forcefield_emitter_on.png",
"technic_forcefield_emitter_on.png",
"technic_forcefield_emitter_on.png"
},
groups = {cracky = 1, technic_machine = 1, technic_hv = 1,
not_in_creative_inventory=1},
drop = "technic:forcefield_emitter_off",
on_receive_fields = forcefield_receive_fields,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local range = meta:get_int("range")
meta:set_string("formspec", get_forcefield_formspec(range))
end,
on_destruct = function(pos)
local meta = minetest.get_meta(pos)
update_forcefield(pos, meta:get_int("range"), false)
update_forcefield(pos, meta, false)
end,
mesecons = mesecons,
digiline = digiline_def,
technic_run = run,
technic_on_disable = function (pos, node)
local meta = minetest.get_meta(pos)
update_forcefield(pos, meta, false)
technic.swap_node(pos, "technic:forcefield_emitter_off")
end,
on_blast = function(pos, intensity)
minetest.dig_node(pos)
return {"technic:forcefield_emitter_off"}
end,
mesecons = mesecons
})
minetest.register_node("technic:forcefield", {
description = S("%s Forcefield"):format("HV"),
sunlight_propagates = true,
drawtype = "glasslike",
groups = {not_in_creative_inventory=1, unbreakable=1},
groups = {not_in_creative_inventory=1},
paramtype = "light",
light_source = 15,
light_source = default.LIGHT_MAX,
diggable = false,
drop = '',
tiles = {{
name = "technic_forcefield_animated.png",
@ -155,53 +364,14 @@ minetest.register_node("technic:forcefield", {
length = 1.0,
},
}},
on_blast = function(pos, intensity)
end,
})
minetest.register_abm({
nodenames = {"technic:forcefield_emitter_on", "technic:forcefield_emitter_off"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local eu_input = meta:get_int("HV_EU_input")
local eu_demand = meta:get_int("HV_EU_demand")
local enabled = meta:get_int("enabled")
local machine_name = S("%s Forcefield Emitter"):format("HV")
-- Power off automatically if no longer connected to a switching station
technic.switching_station_timeout_count(pos, "HV")
local power_requirement = math.floor(
4 * math.pi * math.pow(meta:get_int("range"), 2)
) * forcefield_power_drain
if meta:get_int("enabled") == 0 then
if node.name == "technic:forcefield_emitter_on" then
meta:set_int("HV_EU_demand", 0)
update_forcefield(pos, meta:get_int("range"), false)
technic.swap_node(pos, "technic:forcefield_emitter_off")
meta:set_string("infotext", S("%s Disabled"):format(machine_name))
return
end
elseif eu_input < power_requirement then
meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
if node.name == "technic:forcefield_emitter_on" then
update_forcefield(pos, meta:get_int("range"), false)
technic.swap_node(pos, "technic:forcefield_emitter_off")
end
elseif eu_input >= power_requirement then
if node.name == "technic:forcefield_emitter_off" then
technic.swap_node(pos, "technic:forcefield_emitter_on")
meta:set_string("infotext", S("%s Active"):format(machine_name))
end
update_forcefield(pos, meta:get_int("range"), true)
end
meta:set_int("HV_EU_demand", power_requirement)
end
})
if minetest.get_modpath("mesecons_mvps") then
mesecon:register_mvps_stopper("technic:forcefield")
mesecon.register_mvps_stopper("technic:forcefield")
end
-- TODO: Register a stopper for frames
technic.register_machine("HV", "technic:forcefield_emitter_on", technic.receiver)
technic.register_machine("HV", "technic:forcefield_emitter_off", technic.receiver)

View File

@ -3,8 +3,8 @@ minetest.register_alias("hv_generator", "technic:hv_generator")
minetest.register_craft({
output = 'technic:hv_generator',
recipe = {
{'technic:stainless_steel_ingot', 'technic:mv_generator', 'technic:stainless_steel_ingot'},
{'pipeworks:tube_1', 'technic:hv_transformer', 'pipeworks:tube_1'},
{'technic:carbon_plate', 'technic:mv_generator', 'technic:composite_plate'},
{'pipeworks:tube_1', 'technic:hv_transformer', 'pipeworks:tube_1'},
{'technic:stainless_steel_ingot', 'technic:hv_cable', 'technic:stainless_steel_ingot'},
}
})

View File

@ -1,244 +1,482 @@
-- The enriched uranium rod driven EU generator.
-- A very large and advanced machine providing vast amounts of power.
-- Very efficient but also expensive to run as it needs uranium. (10000EU 86400 ticks (one week))
-- Provides HV EUs that can be down converted as needed.
--
-- The nuclear reactor core needs water and a protective shield to work.
-- This is checked now and then and if the machine is tampered with... BOOM!
--[[
The enriched uranium rod driven EU generator.
A very large and advanced machine providing vast amounts of power.
Very efficient but also expensive to run as it needs uranium.
Provides 10000 HV EUs for one week (only counted when loaded).
local burn_ticks = 7 * 24 * 60 * 60 -- (seconds).
local power_supply = 100000 -- EUs
local fuel_type = "technic:uranium_fuel" -- The reactor burns this stuff
The nuclear reactor core requires a casing of water and a protective
shield to work. This is checked now and then and if the casing is not
intact the reactor will melt down!
--]]
local burn_ticks = 7 * 24 * 60 * 60 -- Seconds
local power_supply = 100000 -- EUs
local fuel_type = "technic:uranium_fuel" -- The reactor burns this
local digiline_meltdown = technic.config:get_bool("enable_nuclear_reactor_digiline_selfdestruct")
local digiline_remote_path = minetest.get_modpath("digiline_remote")
local S = technic.getter
-- FIXME: recipe must make more sense like a rod recepticle, steam chamber, HV generator?
local reactor_desc = S("@1 Nuclear Reactor Core", S("HV"))
local cable_entry = "^technic_cable_connection_overlay.png"
-- FIXME: Recipe should make more sense like a rod recepticle, steam chamber, HV generator?
minetest.register_craft({
output = 'technic:hv_nuclear_reactor_core',
recipe = {
{'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot'},
{'technic:stainless_steel_ingot', '', 'technic:stainless_steel_ingot'},
{'technic:stainless_steel_ingot', 'technic:hv_cable', 'technic:stainless_steel_ingot'},
{'technic:carbon_plate', 'default:obsidian_glass', 'technic:carbon_plate'},
{'technic:composite_plate', 'technic:machine_casing', 'technic:composite_plate'},
{'technic:stainless_steel_ingot', 'technic:hv_cable', 'technic:stainless_steel_ingot'},
}
})
local generator_formspec =
"invsize[8,9;]"..
local function make_reactor_formspec(meta)
local f = "size[8,9]"..
"label[0,0;"..S("Nuclear Reactor Rod Compartment").."]"..
"list[current_name;src;2,1;3,2;]"..
"list[current_player;main;0,5;8,4;]"
"list[current_player;main;0,5;8,4;]"..
"listring[]"..
"button[5.5,1.5;2,1;start;Start]"..
"checkbox[5.5,2.5;autostart;automatic Start;"..meta:get_string("autostart").."]"
if not digiline_remote_path then
return f
end
local digiline_enabled = meta:get_string("enable_digiline")
f = f.."checkbox[0.5,2.8;enable_digiline;Enable Digiline;"..digiline_enabled.."]"
if digiline_enabled ~= "true" then
return f
end
return f..
"button_exit[4.6,3.69;2,1;save;Save]"..
"field[1,4;4,1;remote_channel;Digiline Remote Channel;${remote_channel}]"
end
-- "Boxy sphere"
local nodebox = {
{ -0.353, -0.353, -0.353, 0.353, 0.353, 0.353 }, -- Box
{ -0.495, -0.064, -0.064, 0.495, 0.064, 0.064 }, -- Circle +-x
{ -0.483, -0.128, -0.128, 0.483, 0.128, 0.128 },
{ -0.462, -0.191, -0.191, 0.462, 0.191, 0.191 },
{ -0.433, -0.249, -0.249, 0.433, 0.249, 0.249 },
{ -0.397, -0.303, -0.303, 0.397, 0.303, 0.303 },
{ -0.305, -0.396, -0.305, 0.305, 0.396, 0.305 }, -- Circle +-y
{ -0.250, -0.432, -0.250, 0.250, 0.432, 0.250 },
{ -0.191, -0.461, -0.191, 0.191, 0.461, 0.191 },
{ -0.130, -0.482, -0.130, 0.130, 0.482, 0.130 },
{ -0.066, -0.495, -0.066, 0.066, 0.495, 0.066 },
{ -0.064, -0.064, -0.495, 0.064, 0.064, 0.495 }, -- Circle +-z
{ -0.128, -0.128, -0.483, 0.128, 0.128, 0.483 },
{ -0.191, -0.191, -0.462, 0.191, 0.191, 0.462 },
{ -0.249, -0.249, -0.433, 0.249, 0.249, 0.433 },
{ -0.303, -0.303, -0.397, 0.303, 0.303, 0.397 },
}
local SS_OFF = 0
local SS_DANGER = 1
local SS_CLEAR = 2
minetest.register_node("technic:hv_nuclear_reactor_core", {
description = S("Nuclear %s Generator Core"):format("HV"),
tiles = {"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png"},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
drawtype="nodebox",
paramtype = "light",
stack_max = 1,
node_box = {
type = "fixed",
fixed = nodebox
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Nuclear %s Generator Core"):format("HV"))
meta:set_int("HV_EU_supply", 0)
-- Signal to the switching station that this device burns some
-- sort of fuel and needs special handling
meta:set_int("HV_EU_from_fuel", 1)
meta:set_int("burn_time", 0)
meta:set_string("formspec", generator_formspec)
local inv = meta:get_inventory()
inv:set_size("src", 6)
end,
can_dig = technic.machine_can_dig,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
})
local reactor_siren = {}
local function siren_set_state(pos, state)
local hpos = minetest.hash_node_position(pos)
local siren = reactor_siren[hpos]
if not siren then
if state == SS_OFF then return end
siren = {state=SS_OFF}
reactor_siren[hpos] = siren
end
if state == SS_DANGER and siren.state ~= SS_DANGER then
if siren.handle then minetest.sound_stop(siren.handle) end
siren.handle = minetest.sound_play("technic_hv_nuclear_reactor_siren_danger_loop",
{pos=pos, gain=1.5, loop=true, max_hear_distance=48})
siren.state = SS_DANGER
elseif state == SS_CLEAR then
if siren.handle then minetest.sound_stop(siren.handle) end
local clear_handle = minetest.sound_play("technic_hv_nuclear_reactor_siren_clear",
{pos=pos, gain=1.5, loop=false, max_hear_distance=48})
siren.handle = clear_handle
siren.state = SS_CLEAR
minetest.after(10, function()
if siren.handle ~= clear_handle then return end
minetest.sound_stop(clear_handle)
if reactor_siren[hpos] == siren then
reactor_siren[hpos] = nil
end
end)
elseif state == SS_OFF and siren.state ~= SS_OFF then
if siren.handle then minetest.sound_stop(siren.handle) end
reactor_siren[hpos] = nil
end
end
minetest.register_node("technic:hv_nuclear_reactor_core_active", {
tiles = {"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png"},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, not_in_creative_inventory=1},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
drop="technic:hv_nuclear_reactor_core",
drawtype="nodebox",
light_source = 15,
paramtype = "light",
node_box = {
type = "fixed",
fixed = nodebox
},
can_dig = technic.machine_can_dig,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
})
local function siren_danger(pos, meta)
meta:set_int("siren", 1)
siren_set_state(pos, SS_DANGER)
end
local check_reactor_structure = function(pos)
-- The reactor consists of a 9x9x9 cube structure
-- A cross section through the middle:
-- CCCC CCCC
-- CBBB BBBC
-- CBSS SSBC
-- CBSWWWSBC
-- CBSW#WSBC
-- CBSW|WSBC
-- CBSS|SSBC
-- CBBB|BBBC
-- CCCC|CCCC
-- C = Concrete, B = Blast resistant concrete, S = Stainless Steel,
-- W = water node, # = reactor core, | = HV cable
-- The man-hole and the HV cable is only in the middle
-- The man-hole is optional
local function siren_clear(pos, meta)
if meta:get_int("siren") ~= 0 then
siren_set_state(pos, SS_CLEAR)
meta:set_int("siren", 0)
end
end
--[[
The standard reactor structure consists of a 9x9x9 cube. A cross
section through the middle:
CCCC CCCC
CBBB BBBC
CBLL LLBC
CBLWWWLBC
CBLW#WLBC
CBLW|WLBC
CBLL|LLBC
CBBB|BBBC
CCCC|CCCC
C = Concrete, B = Blast-resistant concrete, L = Lead,
W = water node, # = reactor core, | = HV cable
The man-hole is optional (but necessary for refueling).
For the reactor to operate and not melt down, it insists on the inner
7x7x7 portion (from the core out to the blast-resistant concrete)
being intact. Intactness only depends on the number of nodes of the
right type in each layer. The water layer must have water in all but
at most one node; the steel and blast-resistant concrete layers must
have the right material in all but at most two nodes. The permitted
gaps are meant for the cable and man-hole, but can actually be anywhere
and contain anything. For the reactor to be useful, a cable must
connect to the core, but it can go in any direction.
The outer concrete layer of the standard structure is not required
for the reactor to operate. It is noted here because it used to
be mandatory, and for historical reasons (that it predates the
implementation of radiation) it needs to continue being adequate
shielding of legacy reactors. If it ever ceases to be adequate
shielding for new reactors, legacy ones should be grandfathered.
For legacy reasons, if the reactor has a stainless steel layer instead
of a lead layer it will be converted to a lead layer.
--]]
local function reactor_structure_badness(pos)
local vm = VoxelManip()
local pos1 = vector.subtract(pos, 4)
local pos2 = vector.add(pos, 4)
local pos1 = vector.subtract(pos, 3)
local pos2 = vector.add(pos, 3)
local MinEdge, MaxEdge = vm:read_from_map(pos1, pos2)
local data = vm:get_data()
local area = VoxelArea:new({MinEdge=MinEdge, MaxEdge=MaxEdge})
local c_concrete = minetest.get_content_id("technic:concrete")
local c_blast_concrete = minetest.get_content_id("technic:blast_resistant_concrete")
local c_stainless_steel = minetest.get_content_id("technic:stainless_steel_block")
local c_lead = minetest.get_content_id("technic:lead_block")
local c_steel = minetest.get_content_id("technic:stainless_steel_block")
local c_water_source = minetest.get_content_id("default:water_source")
local c_water_flowing = minetest.get_content_id("default:water_flowing")
local concretelayer, blastlayer, steellayer, waterlayer = 0, 0, 0, 0
local blast_layer, steel_layer, lead_layer, water_layer = 0, 0, 0, 0
for z = pos1.z, pos2.z do
for y = pos1.y, pos2.y do
for x = pos1.x, pos2.x do
-- If the position is in the outer layer
local cid = data[area:index(x, y, z)]
if x == pos1.x or x == pos2.x or
y == pos1.y or y == pos2.y or
z == pos1.z or z == pos2.z then
if data[area:index(x, y, z)] == c_concrete then
concretelayer = concretelayer + 1
if cid == c_blast_concrete then
blast_layer = blast_layer + 1
end
elseif x == pos1.x+1 or x == pos2.x-1 or
y == pos1.y+1 or y == pos2.y-1 or
z == pos1.z+1 or z == pos2.z-1 then
if data[area:index(x, y, z)] == c_blast_concrete then
blastlayer = blastlayer + 1
y == pos1.y+1 or y == pos2.y-1 or
z == pos1.z+1 or z == pos2.z-1 then
if cid == c_lead then
lead_layer = lead_layer + 1
elseif cid == c_steel then
steel_layer = steel_layer + 1
end
elseif x == pos1.x+2 or x == pos2.x-2 or
y == pos1.y+2 or y == pos2.y-2 or
z == pos1.z+2 or z == pos2.z-2 then
if data[area:index(x, y, z)] == c_stainless_steel then
steellayer = steellayer + 1
end
elseif x == pos1.x+3 or x == pos2.x-3 or
y == pos1.y+3 or y == pos2.y-3 or
z == pos1.z+3 or z == pos2.z-3 then
local cid = data[area:index(x, y, z)]
y == pos1.y+2 or y == pos2.y-2 or
z == pos1.z+2 or z == pos2.z-2 then
if cid == c_water_source or cid == c_water_flowing then
waterlayer = waterlayer + 1
water_layer = water_layer + 1
end
end
end
end
end
if waterlayer >= 25 and
steellayer >= 96 and
blastlayer >= 216 and
concretelayer >= 384 then
return true
if steel_layer >= 96 then
for z = pos1.z+1, pos2.z-1 do
for y = pos1.y+1, pos2.y-1 do
for x = pos1.x+1, pos2.x-1 do
local vi = area:index(x, y, z)
if x == pos1.x+1 or x == pos2.x-1 or
y == pos1.y+1 or y == pos2.y-1 or
z == pos1.z+1 or z == pos2.z-1 then
if data[vi] == c_steel then
data[vi] = c_lead
end
end
end
end
end
vm:set_data(data)
vm:write_to_map()
lead_layer = steel_layer
end
if water_layer > 25 then water_layer = 25 end
if lead_layer > 96 then lead_layer = 96 end
if blast_layer > 216 then blast_layer = 216 end
return (25 - water_layer) + (96 - lead_layer) + (216 - blast_layer)
end
local explode_reactor = function(pos)
print("A reactor exploded at "..minetest.pos_to_string(pos))
local function melt_down_reactor(pos)
minetest.log("action", "A reactor melted down at "..minetest.pos_to_string(pos))
minetest.set_node(pos, {name = "technic:corium_source"})
end
local function damage_nearby_players(pos)
local objs = minetest.get_objects_inside_radius(pos, 4)
for _, o in pairs(objs) do
if o:is_player() then
o:set_hp(math.max(o:get_hp() - 2, 0))
local function start_reactor(pos, meta)
if minetest.get_node(pos).name ~= "technic:hv_nuclear_reactor_core" then
return false
end
local inv = meta:get_inventory()
if inv:is_empty("src") then
return false
end
local src_list = inv:get_list("src")
local correct_fuel_count = 0
for _, src_stack in pairs(src_list) do
if src_stack and src_stack:get_name() == fuel_type then
correct_fuel_count = correct_fuel_count + 1
end
end
-- Check that the reactor is complete and has the correct fuel
if correct_fuel_count ~= 6 or reactor_structure_badness(pos) ~= 0 then
return false
end
meta:set_int("burn_time", 1)
technic.swap_node(pos, "technic:hv_nuclear_reactor_core_active")
meta:set_int("HV_EU_supply", power_supply)
for idx, src_stack in pairs(src_list) do
src_stack:take_item()
inv:set_stack("src", idx, src_stack)
end
return true
end
minetest.register_abm({
nodenames = {"technic:hv_nuclear_reactor_core", "technic:hv_nuclear_reactor_core_active"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
label = "Machines: reactor melt-down check",
nodenames = {"technic:hv_nuclear_reactor_core_active"},
interval = 4,
chance = 1,
action = function (pos, node)
local meta = minetest.get_meta(pos)
local machine_name = S("Nuclear %s Generator Core"):format("HV")
local badness = reactor_structure_badness(pos)
local accum_badness = meta:get_int("structure_accumulated_badness")
if badness == 0 then
if accum_badness ~= 0 then
meta:set_int("structure_accumulated_badness", math.max(accum_badness - 4, 0))
siren_clear(pos, meta)
end
else
siren_danger(pos, meta)
accum_badness = accum_badness + badness
if accum_badness >= 25 then
melt_down_reactor(pos)
else
meta:set_int("structure_accumulated_badness", accum_badness)
end
end
end,
})
local function run(pos, node)
local meta = minetest.get_meta(pos)
local burn_time = meta:get_int("burn_time") or 0
if burn_time >= burn_ticks or burn_time == 0 then
if digiline_remote_path and meta:get_int("HV_EU_supply") == power_supply then
digiline_remote.send_to_node(pos, meta:get_string("remote_channel"),
"fuel used", 6, true)
end
if meta:get_string("autostart") == "true" then
if start_reactor(pos, meta) then
return
end
end
meta:set_int("HV_EU_supply", 0)
meta:set_int("burn_time", 0)
meta:set_string("infotext", S("%s Idle"):format(reactor_desc))
technic.swap_node(pos, "technic:hv_nuclear_reactor_core")
meta:set_int("structure_accumulated_badness", 0)
siren_clear(pos, meta)
elseif burn_time > 0 then
burn_time = burn_time + 1
meta:set_int("burn_time", burn_time)
local percent = math.floor(burn_time / burn_ticks * 100)
meta:set_string("infotext", reactor_desc.." ("..percent.."%)")
meta:set_int("HV_EU_supply", power_supply)
end
end
local nuclear_reactor_receive_fields = function(pos, formname, fields, sender)
local player_name = sender:get_player_name()
if minetest.is_protected(pos, player_name) then
minetest.chat_send_player(player_name, "You are not allowed to edit this!")
minetest.record_protection_violation(pos, player_name)
return
end
local meta = minetest.get_meta(pos)
local update_formspec = false
if fields.remote_channel then
meta:set_string("remote_channel", fields.remote_channel)
end
if fields.start then
local b = start_reactor(pos, meta)
if b then
minetest.chat_send_player(player_name, "Start successful")
else
minetest.chat_send_player(player_name, "Error")
end
end
if fields.autostart then
meta:set_string("autostart", fields.autostart)
update_formspec = true
end
if fields.enable_digiline then
meta:set_string("enable_digiline", fields.enable_digiline)
update_formspec = true
end
if update_formspec then
meta:set_string("formspec", make_reactor_formspec(meta))
end
end
local digiline_remote_def = function(pos, channel, msg)
local meta = minetest.get_meta(pos)
if meta:get_string("enable_digiline") ~= "true" or
channel ~= meta:get_string("remote_channel") then
return
end
-- Convert string messages to tables:
local msgt = type(msg)
if msgt == "string" then
local smsg = msg:lower()
msg = {}
if smsg == "get" then
msg.command = "get"
elseif smsg:sub(1, 13) == "self_destruct" then
msg.command = "self_destruct"
msg.timer = tonumber(smsg:sub(15)) or 0
elseif smsg == "start" then
msg.command = "start"
end
elseif msgt ~= "table" then
return
end
if msg.command == "get" then
local inv = meta:get_inventory()
local invtable = {}
for i = 1, 6 do
local stack = inv:get_stack("src", i)
if stack:is_empty() then
invtable[i] = 0
elseif stack:get_name() == fuel_type then
invtable[i] = stack:get_count()
else
invtable[i] = -stack:get_count()
end
end
digiline_remote.send_to_node(pos, channel, {
burn_time = meta:get_int("burn_time"),
enabled = meta:get_int("HV_EU_supply") == power_supply,
siren = meta:get_int("siren") == 1,
structure_accumulated_badness = meta:get_int("structure_accumulated_badness"),
rods = invtable
}, 6, true)
elseif digiline_meltdown and msg.command == "self_destruct" and
minetest.get_node(pos).name == "technic:hv_nuclear_reactor_core_active" then
if msg.timer ~= 0 and type(msg.timer) == "number" then
siren_danger(pos, meta)
minetest.after(msg.timer, melt_down_reactor, pos)
else
melt_down_reactor(pos)
end
elseif msg.command == "start" then
local b = start_reactor(pos, meta)
if b then
digiline_remote.send_to_node(pos, channel, "Start successful", 6, true)
else
digiline_remote.send_to_node(pos, channel, "Error", 6, true)
end
end
end
minetest.register_node("technic:hv_nuclear_reactor_core", {
description = reactor_desc,
tiles = {
"technic_hv_nuclear_reactor_core.png",
"technic_hv_nuclear_reactor_core.png"..cable_entry
},
drawtype = "mesh",
mesh = "technic_reactor.obj",
groups = {cracky = 1, technic_machine = 1, technic_hv = 1, digiline_remote_receive = 1},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
paramtype = "light",
paramtype2 = "facedir",
stack_max = 1,
on_receive_fields = nuclear_reactor_receive_fields,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", reactor_desc)
meta:set_string("formspec", make_reactor_formspec(meta))
if digiline_remote_path then
meta:set_string("remote_channel",
"nucelear_reactor"..minetest.pos_to_string(pos))
end
local inv = meta:get_inventory()
inv:set_size("src", 6)
end,
_on_digiline_remote_receive = digiline_remote_def,
can_dig = technic.machine_can_dig,
on_destruct = function(pos) siren_set_state(pos, SS_OFF) end,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
technic_run = run,
})
minetest.register_node("technic:hv_nuclear_reactor_core_active", {
tiles = {
"technic_hv_nuclear_reactor_core.png",
"technic_hv_nuclear_reactor_core.png"..cable_entry
},
drawtype = "mesh",
mesh = "technic_reactor.obj",
groups = {cracky = 1, technic_machine = 1, technic_hv = 1, radioactive = 4,
not_in_creative_inventory = 1, digiline_remote_receive = 1},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
drop = "technic:hv_nuclear_reactor_core",
light_source = 14,
paramtype = "light",
paramtype2 = "facedir",
on_receive_fields = nuclear_reactor_receive_fields,
_on_digiline_remote_receive = digiline_remote_def,
can_dig = technic.machine_can_dig,
after_dig_node = melt_down_reactor,
on_destruct = function(pos) siren_set_state(pos, SS_OFF) end,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
technic_run = run,
technic_on_disable = function(pos, node)
local timer = minetest.get_node_timer(pos)
timer:start(1)
end,
on_timer = function(pos, node)
local meta = minetest.get_meta(pos)
-- Connected back?
if meta:get_int("HV_EU_timeout") > 0 then return false end
local burn_time = meta:get_int("burn_time") or 0
if burn_time >= burn_ticks or burn_time == 0 then
local inv = meta:get_inventory()
if not inv:is_empty("src") then
local srclist = inv:get_list("src")
local correct_fuel_count = 0
for _, srcstack in pairs(srclist) do
if srcstack then
if srcstack:get_name() == fuel_type then
correct_fuel_count = correct_fuel_count + 1
end
end
end
-- Check that the reactor is complete as well
-- as the correct number of correct fuel
if correct_fuel_count == 6 and
check_reactor_structure(pos) then
meta:set_int("burn_time", 1)
technic.swap_node(pos, "technic:hv_nuclear_reactor_core_active")
meta:set_int("HV_EU_supply", power_supply)
for idx, srcstack in pairs(srclist) do
srcstack:take_item()
inv:set_stack("src", idx, srcstack)
end
return
end
end
meta:set_int("HV_EU_supply", 0)
meta:set_int("burn_time", 0)
meta:set_string("infotext", S("%s Idle"):format(machine_name))
technic.swap_node(pos, "technic:hv_nuclear_reactor_core")
elseif burn_time > 0 then
damage_nearby_players(pos)
if not check_reactor_structure(pos) then
explode_reactor(pos)
end
burn_time = burn_time + 1
meta:set_int("burn_time", burn_time)
local percent = math.floor(burn_time / burn_ticks * 100)
meta:set_string("infotext", machine_name.." ("..percent.."%)")
meta:set_int("HV_EU_supply", power_supply)
meta:set_int("structure_accumulated_badness", 0)
siren_clear(pos, meta)
return false
end
end
meta:set_int("burn_time", burn_time + 1)
return true
end,
})
technic.register_machine("HV", "technic:hv_nuclear_reactor_core", technic.producer)

View File

@ -1,193 +1,269 @@
local S = technic.getter
local tube_entry = "^pipeworks_tube_connection_metallic.png"
local cable_entry = "^technic_cable_connection_overlay.png"
minetest.register_craft({
recipe = {
{"technic:carbon_steel_block", "pipeworks:filter", "technic:carbon_steel_block"},
{"technic:carbon_steel_block", "technic:motor", "technic:carbon_steel_block"},
{"technic:carbon_steel_block", "technic:diamond_drill_head", "technic:carbon_steel_block"}},
{"technic:carbon_plate", "pipeworks:filter", "technic:composite_plate"},
{"technic:motor", "technic:machine_casing", "technic:diamond_drill_head"},
{"technic:carbon_steel_block", "technic:hv_cable", "technic:carbon_steel_block"}},
output = "technic:quarry",
})
local quarry_dig_above_nodes = 3 -- How far above the quarry we will dig nodes
local quarry_max_depth = 100
local quarry_demand = 10000
local quarry_eject_dir = vector.new(0, 1, 0)
local function set_quarry_formspec(meta)
local formspec = "size[3,1.5]"..
"field[1,0.5;2,1;size;Radius;"..meta:get_int("size").."]"
local radius = meta:get_int("size")
local formspec = "size[6,4.3]"..
"list[context;cache;0,1;4,3;]"..
"item_image[4.8,0;1,1;technic:quarry]"..
"label[0,0.2;"..S("%s Quarry"):format("HV").."]"..
"field[4.3,3.5;2,1;size;"..S("Radius:")..";"..radius.."]"
if meta:get_int("enabled") == 0 then
formspec = formspec.."button[0,1;3,1;enable;"..S("%s Disabled"):format(S("%s Quarry"):format("HV")).."]"
formspec = formspec.."button[4,1;2,1;enable;"..S("Disabled").."]"
else
formspec = formspec.."button[0,1;3,1;disable;"..S("%s Enabled"):format(S("%s Quarry"):format("HV")).."]"
formspec = formspec.."button[4,1;2,1;disable;"..S("Enabled").."]"
end
local diameter = radius*2 + 1
local nd = meta:get_int("dug")
local rel_y = quarry_dig_above_nodes - math.floor(nd / (diameter*diameter))
formspec = formspec.."label[0,4;"..minetest.formspec_escape(
nd == 0 and S("Digging not started") or
(rel_y < -quarry_max_depth and S("Digging finished") or
(meta:get_int("purge_on") == 1 and S("Purging cache") or
S("Digging %d m "..(rel_y > 0 and "above" or "below").." machine")
:format(math.abs(rel_y))))
).."]"
formspec = formspec.."button[4,2;2,1;restart;"..S("Restart").."]"
meta:set_string("formspec", formspec)
end
local function set_quarry_demand(meta)
local radius = meta:get_int("size")
local diameter = radius*2 + 1
local machine_name = S("%s Quarry"):format("HV")
if meta:get_int("enabled") == 0 or meta:get_int("purge_on") == 1 then
meta:set_string("infotext", S(meta:get_int("purge_on") == 1 and "%s purging cache" or "%s Disabled"):format(machine_name))
meta:set_int("HV_EU_demand", 0)
elseif meta:get_int("dug") == diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) then
meta:set_string("infotext", S("%s Finished"):format(machine_name))
meta:set_int("HV_EU_demand", 0)
else
meta:set_string("infotext", S(meta:get_int("HV_EU_input") >= quarry_demand and "%s Active" or "%s Unpowered"):format(machine_name))
meta:set_int("HV_EU_demand", quarry_demand)
end
end
local function quarry_receive_fields(pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
if fields.size then
local size = tonumber(fields.size) or 0
size = math.max(size, 2)
size = math.min(size, 8)
meta:set_int("size", size)
if fields.size and string.find(fields.size, "^[0-9]+$") then
local size = tonumber(fields.size)
if size >= 2 and size <= 8 and size ~= meta:get_int("size") then
meta:set_int("size", size)
meta:set_int("dug", 0)
end
end
if fields.enable then meta:set_int("enabled", 1) end
if fields.disable then meta:set_int("enabled", 0) end
if fields.restart then
meta:set_int("dug", 0)
meta:set_int("purge_on", 1)
end
set_quarry_formspec(meta)
set_quarry_demand(meta)
end
local function get_quarry_center(pos, size)
local node = minetest.get_node(pos)
local back_dir = minetest.facedir_to_dir(node.param2)
local relative_center = vector.multiply(back_dir, size + 1)
local center = vector.add(pos, relative_center)
return center
end
local function gen_next_digpos(center, digpos, size)
digpos.x = digpos.x + 1
if digpos.x > center.x + size then
digpos.x = center.x - size
digpos.z = digpos.z + 1
end
if digpos.z > center.z + size then
digpos.x = center.x - size
digpos.z = center.z - size
digpos.y = digpos.y - 1
end
end
local function find_next_digpos(data, area, center, dig_y, size)
local c_air = minetest.get_content_id("air")
for y = center.y + quarry_dig_above_nodes, dig_y - 1, -1 do
for z = center.z - size, center.z + size do
for x = center.x - size, center.x + size do
if data[area:index(x, y, z)] ~= c_air then
return vector.new(x, y, z)
end
end
end
end
end
local function quarry_dig(pos, center, size)
local function quarry_handle_purge(pos)
local meta = minetest.get_meta(pos)
local drops = {}
local dig_y = meta:get_int("dig_y")
local owner = meta:get_string("owner")
local vm = VoxelManip()
local p1 = vector.new(
center.x - size,
center.y + quarry_dig_above_nodes,
center.z - size)
local p2 = vector.new(
center.x + size,
dig_y - 1, -- One node lower in case we have finished the current layer
center.z + size)
local e1, e2 = vm:read_from_map(p1, p2)
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
local data = vm:get_data()
local digpos = find_next_digpos(data, area, center, dig_y, size)
if digpos then
if digpos.y < pos.y - quarry_max_depth then
meta:set_int("dig_y", digpos.y)
return drops
local inv = meta:get_inventory()
local i = 0
for _,stack in ipairs(inv:get_list("cache")) do
i = i + 1
if stack then
local item = stack:to_table()
if item then
technic.tube_inject_item(pos, pos, quarry_eject_dir, item)
stack:clear()
inv:set_stack("cache", i, stack)
break
end
end
if minetest.is_protected and minetest.is_protected(digpos, owner) then
meta:set_int("enabled", 0)
set_quarry_formspec(meta)
return {}
end
dig_y = digpos.y
local node = minetest.get_node(digpos)
local node_def = minetest.registered_nodes[node.name] or { diggable = false }
if node_def.diggable and ((not node_def.can_dig) or node_def.can_dig(digpos, nil)) then
minetest.remove_node(digpos)
drops = minetest.get_node_drops(node.name, "")
end
elseif not (dig_y < pos.y - quarry_max_depth) then
dig_y = dig_y - 16
end
meta:set_int("dig_y", dig_y)
return drops
if inv:is_empty("cache") then
meta:set_int("purge_on", 0)
end
end
local function send_items(items, pos, node)
for _, item in pairs(items) do
local tube_item = pipeworks.tube_item(vector.new(pos), item)
tube_item:get_luaentity().start_pos = vector.new(pos)
tube_item:setvelocity(vector.new(0, 1, 0))
tube_item:setacceleration({x=0, y=0, z=0})
local function quarry_run(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
-- initialize cache for the case we load an older world
inv:set_size("cache", 12)
-- toss a coin whether we do an automatic purge. Chance 1:200
local purge_rand = math.random()
if purge_rand <= 0.005 then
meta:set_int("purge_on", 1)
end
if meta:get_int("enabled") and meta:get_int("HV_EU_input") >= quarry_demand and meta:get_int("purge_on") == 0 then
local pdir = minetest.facedir_to_dir(node.param2)
local qdir = pdir.x == 1 and vector.new(0,0,-1) or
(pdir.z == -1 and vector.new(-1,0,0) or
(pdir.x == -1 and vector.new(0,0,1) or
vector.new(1,0,0)))
local radius = meta:get_int("size")
local diameter = radius*2 + 1
local startpos = vector.add(vector.add(vector.add(pos,
vector.new(0, quarry_dig_above_nodes, 0)),
pdir),
vector.multiply(qdir, -radius))
local owner = meta:get_string("owner")
local nd = meta:get_int("dug")
while nd ~= diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) do
local ry = math.floor(nd / (diameter*diameter))
local ndl = nd % (diameter*diameter)
if ry % 2 == 1 then
ndl = diameter*diameter - 1 - ndl
end
local rq = math.floor(ndl / diameter)
local rp = ndl % diameter
if rq % 2 == 1 then rp = diameter - 1 - rp end
local digpos = vector.add(vector.add(vector.add(startpos,
vector.new(0, -ry, 0)),
vector.multiply(pdir, rp)),
vector.multiply(qdir, rq))
local can_dig = true
if can_dig and minetest.is_protected and minetest.is_protected(digpos, owner) then
can_dig = false
end
local dignode
if can_dig then
dignode = technic.get_or_load_node(digpos) or minetest.get_node(digpos)
local dignodedef = minetest.registered_nodes[dignode.name] or {diggable=false}
-- doors mod among other thing does NOT like a nil digger...
local fakedigger = {
get_player_name = function()
return "!technic_quarry_fake_digger"
end,
is_player = function() return false end,
get_wielded_item = function()
return ItemStack("air")
end,
}
if not dignodedef.diggable or (dignodedef.can_dig and not dignodedef.can_dig(digpos, fakedigger)) then
can_dig = false
end
end
if can_dig then
for ay = startpos.y, digpos.y+1, -1 do
local checkpos = {x=digpos.x, y=ay, z=digpos.z}
local checknode = technic.get_or_load_node(checkpos) or minetest.get_node(checkpos)
if checknode.name ~= "air" then
can_dig = false
break
end
end
end
nd = nd + 1
if can_dig then
minetest.remove_node(digpos)
local drops = minetest.get_node_drops(dignode.name, "")
for _, dropped_item in ipairs(drops) do
local left = inv:add_item("cache", dropped_item)
while not left:is_empty() do
meta:set_int("purge_on", 1)
quarry_handle_purge(pos)
left = inv:add_item("cache", left)
end
end
break
end
end
if nd == diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) then
-- if a quarry is finished, we enable purge mode
meta:set_int("purge_on", 1)
end
meta:set_int("dug", nd)
else
-- if a quarry is disabled or has no power, we enable purge mode
meta:set_int("purge_on", 1)
end
-- if something triggered a purge, we handle it
if meta:get_int("purge_on") == 1 then
quarry_handle_purge(pos)
end
set_quarry_formspec(meta)
set_quarry_demand(meta)
end
local function send_move_error(player)
minetest.chat_send_player(player:get_player_name(),
S("Manually taking/removing from cache by hand is not possible. "..
"If you can't wait, restart or disable the quarry to start automatic purge."))
return 0
end
minetest.register_node("technic:quarry", {
description = S("%s Quarry"):format("HV"),
tiles = {"technic_carbon_steel_block.png", "technic_carbon_steel_block.png",
"technic_carbon_steel_block.png", "technic_carbon_steel_block.png",
"technic_carbon_steel_block.png^default_tool_mesepick.png", "technic_carbon_steel_block.png"},
tiles = {
"technic_carbon_steel_block.png"..tube_entry,
"technic_carbon_steel_block.png"..cable_entry,
"technic_carbon_steel_block.png"..cable_entry,
"technic_carbon_steel_block.png"..cable_entry,
"technic_carbon_steel_block.png^default_tool_mesepick.png",
"technic_carbon_steel_block.png"..cable_entry
},
paramtype2 = "facedir",
groups = {cracky=2, tubedevice=1},
groups = {cracky=2, tubedevice=1, technic_machine=1, technic_hv=1},
connect_sides = {"bottom", "front", "left", "right"},
tube = {
connect_sides = {top = 1},
-- lower priority than other tubes, so that quarries will prefer any
-- other tube to another quarry, which could lead to server freezes
-- in certain quarry placements (2x2 for example would never eject)
priority = 10,
can_go = function(pos, node, velocity, stack)
-- always eject the same, even if items came in another way
-- this further mitigates loops and generally avoids random sideway movement
-- that can be expected in certain quarry placements
return { quarry_eject_dir }
end
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("%s Quarry"):format("HV"))
meta:set_int("size", 4)
set_quarry_formspec(meta)
meta:set_int("dig_y", pos.y)
set_quarry_demand(meta)
end,
after_place_node = function(pos, placer, itemstack)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name())
pipeworks.scan_for_tube_objects(pos)
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("cache")
end,
after_dig_node = pipeworks.scan_for_tube_objects,
on_receive_fields = quarry_receive_fields,
})
minetest.register_abm({
nodenames = {"technic:quarry"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local size = meta:get_int("size")
local eu_input = meta:get_int("HV_EU_input")
local demand = 10000
local center = get_quarry_center(pos, size)
local dig_y = meta:get_int("dig_y")
local machine_name = S("%s Quarry"):format("HV")
technic.switching_station_timeout_count(pos, "HV")
if meta:get_int("enabled") == 0 then
meta:set_string("infotext", S("%s Disabled"):format(machine_name))
meta:set_int("HV_EU_demand", 0)
return
end
if eu_input < demand then
meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
elseif eu_input >= demand then
meta:set_string("infotext", S("%s Active"):format(machine_name))
local items = quarry_dig(pos, center, size)
send_items(items, pos, node)
if dig_y < pos.y - quarry_max_depth then
meta:set_string("infotext", S("%s Finished"):format(machine_name))
end
end
meta:set_int("HV_EU_demand", demand)
technic_run = quarry_run,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
return send_move_error(player)
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
return send_move_error(player)
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
return send_move_error(player)
end
})
technic.register_machine("HV", "technic:quarry", technic.receiver)

View File

@ -5,8 +5,8 @@ minetest.register_craft({
output = 'technic:solar_array_hv 1',
recipe = {
{'technic:solar_array_mv', 'technic:solar_array_mv', 'technic:solar_array_mv'},
{'technic:carbon_steel_ingot', 'technic:hv_transformer', 'technic:carbon_steel_ingot'},
{'', 'technic:hv_cable0', ''},
{'technic:carbon_plate', 'technic:hv_transformer', 'technic:composite_plate'},
{'', 'technic:hv_cable', ''},
}
})

View File

@ -4,9 +4,9 @@
minetest.register_craft({
output = 'technic:lv_alloy_furnace',
recipe = {
{'default:brick', 'default:brick', 'default:brick'},
{'default:brick', '', 'default:brick'},
{'technic:cast_iron_ingot', 'default:copper_ingot', 'technic:cast_iron_ingot'},
{'default:brick', 'default:brick', 'default:brick'},
{'default:brick', 'technic:machine_casing', 'default:brick'},
{'default:brick', 'technic:lv_cable', 'default:brick'},
}
})

View File

@ -1,10 +1,11 @@
-- LV Battery box
minetest.register_craft({
output = 'technic:lv_battery_box0',
recipe = {
{'technic:battery', 'group:wood', 'technic:battery'},
{'technic:battery', 'default:copper_ingot', 'technic:battery'},
{'technic:cast_iron_ingot', 'technic:cast_iron_ingot', 'technic:cast_iron_ingot'},
{'group:wood', 'group:wood', 'group:wood'},
{'technic:battery', 'technic:machine_casing', 'technic:battery'},
{'technic:battery', 'technic:lv_cable', 'technic:battery'},
}
})

View File

@ -1,10 +1,12 @@
minetest.register_alias("lv_cable", "technic:lv_cable0")
minetest.register_alias("lv_cable", "technic:lv_cable")
minetest.register_craft({
output = 'technic:lv_cable0 6',
output = 'technic:lv_cable 6',
recipe = {
{'default:paper', 'default:paper', 'default:paper'},
{'default:copper_ingot', 'default:copper_ingot', 'default:copper_ingot'},
{'default:paper', 'default:paper', 'default:paper'},
}
})

View File

@ -9,6 +9,17 @@
local S = technic.getter
minetest.register_craft({
output = 'technic:cnc',
recipe = {
{'default:glass', 'technic:diamond_drill_head', 'default:glass'},
{'technic:control_logic_unit', 'technic:machine_casing', 'technic:motor'},
{'technic:carbon_steel_ingot', 'technic:lv_cable', 'technic:carbon_steel_ingot'},
},
})
local shape = {}
local onesize_products = {
slope = 2,
@ -17,6 +28,7 @@ local onesize_products = {
pyramid = 2,
spike = 1,
cylinder = 2,
oblate_spheroid = 1,
sphere = 1,
stick = 8,
slope_upsdown = 2,
@ -36,7 +48,7 @@ local twosize_products = {
}
local cnc_formspec =
"invsize[9,11;]"..
"size[9,11;]"..
"label[1,0;"..S("Choose Milling Program:").."]"..
"image_button[1,0.5;1,1;technic_cnc_slope.png;slope; ]"..
"image_button[2,0.5;1,1;technic_cnc_slope_edge.png;slope_edge; ]"..
@ -44,13 +56,14 @@ local cnc_formspec =
"image_button[4,0.5;1,1;technic_cnc_pyramid.png;pyramid; ]"..
"image_button[5,0.5;1,1;technic_cnc_spike.png;spike; ]"..
"image_button[6,0.5;1,1;technic_cnc_cylinder.png;cylinder; ]"..
"image_button[7,0.5;1,1;technic_cnc_sphere.png;sphere; ]"..
"image_button[7,0.5;1,1;technic_cnc_oblate_spheroid.png;oblate_spheroid; ]"..
"image_button[8,0.5;1,1;technic_cnc_stick.png;stick; ]"..
"image_button[1,1.5;1,1;technic_cnc_slope_upsdwn.png;slope_upsdown; ]"..
"image_button[2,1.5;1,1;technic_cnc_slope_edge_upsdwn.png;slope_edge_upsdown; ]"..
"image_button[3,1.5;1,1;technic_cnc_slope_inner_edge_upsdwn.png;slope_inner_edge_upsdown; ]"..
"image_button[4,1.5;1,1;technic_cnc_cylinder_horizontal.png;cylinder_horizontal; ]"..
"image_button[5,1.5;1,1;technic_cnc_sphere.png;sphere; ]"..
"image_button[1,2.5;1,1;technic_cnc_slope_lying.png;slope_lying; ]"..
"image_button[2,2.5;1,1;technic_cnc_onecurvededge.png;onecurvededge; ]"..
@ -71,7 +84,11 @@ local cnc_formspec =
"label[4, 5.5;"..S("Out:").."]"..
"list[current_name;dst;5,5.5;4,1;]"..
"list[current_player;main;0,7;8,4;]"
"list[current_player;main;0,7;8,4;]"..
"listring[current_name;dst]"..
"listring[current_player;main]"..
"listring[current_name;src]"..
"listring[current_player;main]"
local size = 1;
@ -125,21 +142,52 @@ local function form_handler(pos, formname, fields, sender)
return
end
-- Action code performing the transformation
local run = function(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local eu_input = meta:get_int("LV_EU_input")
local machine_name = S("%s CNC Machine"):format("LV")
local machine_node = "technic:cnc"
local demand = 450
local result = meta:get_string("cnc_product")
if inv:is_empty("src") or
(not minetest.registered_nodes[result]) or
(not inv:room_for_item("dst", result)) then
technic.swap_node(pos, machine_node)
meta:set_string("infotext", S("%s Idle"):format(machine_name))
meta:set_string("cnc_product", "")
meta:set_int("LV_EU_demand", 0)
return
end
if eu_input < demand then
technic.swap_node(pos, machine_node)
meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
elseif eu_input >= demand then
technic.swap_node(pos, machine_node.."_active")
meta:set_string("infotext", S("%s Active"):format(machine_name))
meta:set_int("src_time", meta:get_int("src_time") + 1)
if meta:get_int("src_time") >= 3 then -- 3 ticks per output
meta:set_int("src_time", 0)
srcstack = inv:get_stack("src", 1)
srcstack:take_item()
inv:set_stack("src", 1, srcstack)
inv:add_item("dst", result.." "..meta:get_int("cnc_multiplier"))
end
end
meta:set_int("LV_EU_demand", demand)
end
-- The actual block inactive state
minetest.register_node("technic:cnc", {
description = S("%s CNC Machine"):format("LV"),
tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png",
"technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front.png"},
drawtype = "nodebox",
paramtype = "light",
groups = {cracky=2, technic_machine=1, technic_lv=1},
connect_sides = {"bottom", "back", "left", "right"},
paramtype2 = "facedir",
node_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
},
},
groups = {cracky=2},
legacy_facedir_simple = true,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
@ -155,6 +203,7 @@ minetest.register_node("technic:cnc", {
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
on_receive_fields = form_handler,
technic_run = run,
})
-- Active state block
@ -162,75 +211,20 @@ minetest.register_node("technic:cnc_active", {
description = S("%s CNC Machine"):format("LV"),
tiles = {"technic_cnc_top_active.png", "technic_cnc_bottom.png", "technic_cnc_side.png",
"technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front_active.png"},
groups = {cracky=2, technic_machine=1, technic_lv=1, not_in_creative_inventory=1},
connect_sides = {"bottom", "back", "left", "right"},
paramtype2 = "facedir",
drop = "technic:cnc",
groups = {cracky=2, not_in_creative_inventory=1},
legacy_facedir_simple = true,
can_dig = technic.machine_can_dig,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
on_receive_fields = form_handler,
technic_run = run,
technic_disabled_machine_name = "technic:cnc",
})
-- Action code performing the transformation
minetest.register_abm({
nodenames = {"technic:cnc","technic:cnc_active"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local eu_input = meta:get_int("LV_EU_input")
local machine_name = S("%s CNC Machine"):format("LV")
local machine_node = "technic:cnc"
local demand = 450
-- Power off automatically if no longer connected to a switching station
technic.switching_station_timeout_count(pos, "LV")
local result = meta:get_string("cnc_product")
if inv:is_empty("src") or
(not minetest.registered_nodes[result]) or
(not inv:room_for_item("dst", result)) then
technic.swap_node(pos, machine_node)
meta:set_string("infotext", S("%s Idle"):format(machine_name))
meta:set_string("cnc_product", "")
meta:set_int("LV_EU_demand", 0)
return
end
if eu_input < demand then
technic.swap_node(pos, machine_node)
meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
elseif eu_input >= demand then
technic.swap_node(pos, machine_node.."_active")
meta:set_string("infotext", S("%s Active"):format(machine_name))
meta:set_int("src_time", meta:get_int("src_time") + 1)
if meta:get_int("src_time") >= 3 then -- 3 ticks per output
meta:set_int("src_time", 0)
srcstack = inv:get_stack("src", 1)
srcstack:take_item()
inv:set_stack("src", 1, srcstack)
inv:add_item("dst", result.." "..meta:get_int("cnc_multiplier"))
end
end
meta:set_int("LV_EU_demand", demand)
end
})
technic.register_machine("LV", "technic:cnc", technic.receiver)
technic.register_machine("LV", "technic:cnc_active", technic.receiver)
-------------------------
-- CNC Machine Recipe
-------------------------
minetest.register_craft({
output = 'technic:cnc',
recipe = {
{'default:glass', 'technic:diamond_drill_head', 'default:glass'},
{'technic:control_logic_unit', 'technic:motor', 'technic:carbon_steel_ingot'},
{'technic:carbon_steel_ingot', 'default:copper_ingot', 'technic:carbon_steel_ingot'},
},
})

View File

@ -5,293 +5,305 @@ local S = technic.getter
technic.cnc = {}
technic.cnc.detail_level = 16
-- REGISTER NONCUBIC FORMS, CREATE MODELS AND RECIPES:
------------------------------------------------------
local function cnc_sphere()
local nodebox = {}
local detail = technic.cnc.detail_level
local sehne
for i = 1, detail - 1 do
sehne = math.sqrt(0.25 - (((i / detail) - 0.5) ^ 2))
nodebox[i]={-sehne, (i/detail) - 0.5, -sehne, sehne, (i/detail)+(1/detail)-0.5, sehne}
end
return nodebox
end
local function cnc_cylinder_horizontal()
local nodebox = {}
local detail = technic.cnc.detail_level
local sehne
for i = 1, detail - 1 do
sehne = math.sqrt(0.25 - (((i / detail) - 0.5) ^ 2))
nodebox[i]={-0.5, (i/detail)-0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, sehne}
end
return nodebox
end
local function cnc_cylinder()
local nodebox = {}
local detail = technic.cnc.detail_level
local sehne
for i = 1, detail - 1 do
sehne = math.sqrt(0.25 - (((i / detail) - 0.5) ^ 2))
nodebox[i]={(i/detail) - 0.5, -0.5, -sehne, (i/detail)+(1/detail)-0.5, 0.5, sehne}
end
return nodebox
end
local function cnc_twocurvededge()
local nodebox = {}
local detail = technic.cnc.detail_level * 2
local sehne
for i = (detail / 2) - 1, detail - 1 do
sehne = math.sqrt(0.25 - (((i / detail) - 0.5) ^ 2))
nodebox[i]={-sehne, -0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, 0.5}
end
return nodebox
end
local function cnc_onecurvededge()
local nodebox = {}
local detail = technic.cnc.detail_level * 2
local sehne
for i = (detail / 2) - 1, detail - 1 do
sehne = math.sqrt(0.25 - (((i / detail) - 0.5) ^ 2))
nodebox[i]={-0.5, -0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, 0.5}
end
return nodebox
end
local function cnc_spike()
local nodebox = {}
local detail = technic.cnc.detail_level
for i = 0, detail - 1 do
nodebox[i+1] = {(i/detail/2)-0.5, (i/detail/2)-0.5, (i/detail/2)-0.5,
0.5-(i/detail/2), (i/detail)-0.5+(1/detail), 0.5-(i/detail/2)}
end
return nodebox
end
local function cnc_pyramid()
local nodebox = {}
local detail = technic.cnc.detail_level / 2
for i = 0, detail - 1 do
nodebox[i+1] = {(i/detail/2)-0.5, (i/detail/2)-0.5, (i/detail/2)-0.5, 0.5-(i/detail/2), (i/detail/2)-0.5+(1/detail), 0.5-(i/detail/2)}
end
return nodebox
end
local function cnc_slope_inner_edge_upsdown()
local nodebox = {}
local detail = technic.cnc.detail_level
for i = 0, detail-1 do
nodebox[i+1] = {0.5-(i/detail)-(1/detail), (i/detail)-0.5, -0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5}
nodebox[i+detail+1] = {-0.5, (i/detail)-0.5, 0.5-(i/detail)-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5}
end
return nodebox
end
local function cnc_slope_edge_upsdown()
local nodebox = {}
local detail = technic.cnc.detail_level
for i = 0, detail-1 do
nodebox[i+1] = {(-1*(i/detail))+0.5-(1/detail), (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5}
end
return nodebox
end
local function cnc_slope_inner_edge()
local nodebox = {}
local detail = technic.cnc.detail_level
for i = 0, detail-1 do
nodebox[i+1] = {(i/detail)-0.5, -0.5, -0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5}
nodebox[i+detail+1] = {-0.5, -0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5}
end
return nodebox
end
local function cnc_slope_edge()
local nodebox = {}
local detail = technic.cnc.detail_level
for i = 0, detail-1 do
nodebox[i+1] = {(i/detail)-0.5, -0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5}
end
return nodebox
end
local function cnc_slope_upsdown()
local nodebox = {}
local detail = technic.cnc.detail_level
for i = 0, detail-1 do
nodebox[i+1] = {-0.5, (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5}
end
return nodebox
end
local function cnc_slope_lying()
local nodebox = {}
local detail = technic.cnc.detail_level
for i = 0, detail-1 do
nodebox[i+1] = {(i/detail)-0.5, -0.5, (i/detail)-0.5, (i/detail)-0.5+(1/detail), 0.5 , 0.5}
end
return nodebox
end
local function cnc_slope()
local nodebox = {}
local detail = technic.cnc.detail_level
for i = 0, detail-1 do
nodebox[i+1] = {-0.5, (i/detail)-0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5}
end
return nodebox
end
-- Define slope boxes for the various nodes
-------------------------------------------
technic.cnc.programs = {
{suffix = "technic_cnc_stick",
nodebox = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15},
desc = S("Stick")},
{ suffix = "technic_cnc_stick",
model = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15},
desc = S("Stick")
},
{suffix = "technic_cnc_element_end_double",
nodebox = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.5},
desc = S("Element End Double")},
{ suffix = "technic_cnc_element_end_double",
model = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.5},
desc = S("Element End Double")
},
{suffix = "technic_cnc_element_cross_double",
nodebox = {
{0.3, -0.5, -0.3, 0.5, 0.5, 0.3},
{-0.3, -0.5, -0.5, 0.3, 0.5, 0.5},
{-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}},
desc = S("Element Cross Double")},
{ suffix = "technic_cnc_element_cross_double",
model = {
{0.3, -0.5, -0.3, 0.5, 0.5, 0.3},
{-0.3, -0.5, -0.5, 0.3, 0.5, 0.5},
{-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}},
desc = S("Element Cross Double")
},
{suffix = "technic_cnc_element_t_double",
nodebox = {
{-0.3, -0.5, -0.5, 0.3, 0.5, 0.3},
{-0.5, -0.5, -0.3, -0.3, 0.5, 0.3},
{0.3, -0.5, -0.3, 0.5, 0.5, 0.3}},
desc = S("Element T Double")},
{ suffix = "technic_cnc_element_t_double",
model = {
{-0.3, -0.5, -0.5, 0.3, 0.5, 0.3},
{-0.5, -0.5, -0.3, -0.3, 0.5, 0.3},
{0.3, -0.5, -0.3, 0.5, 0.5, 0.3}},
desc = S("Element T Double")
},
{suffix = "technic_cnc_element_edge_double",
nodebox = {
{-0.3, -0.5, -0.5, 0.3, 0.5, 0.3},
{-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}},
desc = S("Element Edge Double")},
{ suffix = "technic_cnc_element_edge_double",
model = {
{-0.3, -0.5, -0.5, 0.3, 0.5, 0.3},
{-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}},
desc = S("Element Edge Double")
},
{suffix = "technic_cnc_element_straight_double",
nodebox = {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5},
desc = S("Element Straight Double")},
{ suffix = "technic_cnc_element_straight_double",
model = {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5},
desc = S("Element Straight Double")
},
{suffix = "technic_cnc_element_end",
nodebox = {-0.3, -0.5, -0.3, 0.3, 0, 0.5},
desc = S("Element End")},
{ suffix = "technic_cnc_element_end",
model = {-0.3, -0.5, -0.3, 0.3, 0, 0.5},
desc = S("Element End")
},
{suffix = "technic_cnc_element_cross",
nodebox = {
{0.3, -0.5, -0.3, 0.5, 0, 0.3},
{-0.3, -0.5, -0.5, 0.3, 0, 0.5},
{-0.5, -0.5, -0.3, -0.3, 0, 0.3}},
desc = S("Element Cross")},
{ suffix = "technic_cnc_element_cross",
model = {
{0.3, -0.5, -0.3, 0.5, 0, 0.3},
{-0.3, -0.5, -0.5, 0.3, 0, 0.5},
{-0.5, -0.5, -0.3, -0.3, 0, 0.3}},
desc = S("Element Cross")
},
{suffix = "technic_cnc_element_t",
nodebox = {
{-0.3, -0.5, -0.5, 0.3, 0, 0.3},
{-0.5, -0.5, -0.3, -0.3, 0, 0.3},
{0.3, -0.5, -0.3, 0.5, 0, 0.3}},
desc = S("Element T")},
{ suffix = "technic_cnc_element_t",
model = {
{-0.3, -0.5, -0.5, 0.3, 0, 0.3},
{-0.5, -0.5, -0.3, -0.3, 0, 0.3},
{0.3, -0.5, -0.3, 0.5, 0, 0.3}},
desc = S("Element T")
},
{suffix = "technic_cnc_element_edge",
nodebox = {
{-0.3, -0.5, -0.5, 0.3, 0, 0.3},
{-0.5, -0.5, -0.3, -0.3, 0, 0.3}},
desc = S("Element Edge")},
{ suffix = "technic_cnc_element_edge",
model = {
{-0.3, -0.5, -0.5, 0.3, 0, 0.3},
{-0.5, -0.5, -0.3, -0.3, 0, 0.3}},
desc = S("Element Edge")
},
{suffix = "technic_cnc_element_straight",
nodebox = {-0.3, -0.5, -0.5, 0.3, 0, 0.5},
desc = S("Element Straight")},
{ suffix = "technic_cnc_element_straight",
model = {-0.3, -0.5, -0.5, 0.3, 0, 0.5},
desc = S("Element Straight")
},
{suffix = "technic_cnc_sphere",
nodebox = cnc_sphere(),
desc = S("Sphere")},
{ suffix = "technic_cnc_oblate_spheroid",
model = "technic_oblate_spheroid.obj",
desc = S("Oblate spheroid"),
cbox = {
type = "fixed",
fixed = {
{ -6/16, 4/16, -6/16, 6/16, 8/16, 6/16 },
{ -8/16, -4/16, -8/16, 8/16, 4/16, 8/16 },
{ -6/16, -8/16, -6/16, 6/16, -4/16, 6/16 }
}
}
},
{suffix = "technic_cnc_cylinder_horizontal",
nodebox = cnc_cylinder_horizontal(),
desc = S("Horizontal Cylinder")},
{ suffix = "technic_cnc_sphere",
model = "technic_sphere.obj",
desc = S("Sphere")
},
{suffix = "technic_cnc_cylinder",
nodebox = cnc_cylinder(),
desc = S("Cylinder")},
{ suffix = "technic_cnc_cylinder_horizontal",
model = "technic_cylinder_horizontal.obj",
desc = S("Horizontal Cylinder")
},
{suffix = "technic_cnc_twocurvededge",
nodebox = cnc_twocurvededge(),
desc = S("Two Curved Edge Block")},
{ suffix = "technic_cnc_cylinder",
model = "technic_cylinder.obj",
desc = S("Cylinder")
},
{suffix = "technic_cnc_onecurvededge",
nodebox = cnc_onecurvededge(),
desc = S("One Curved Edge Block")},
{ suffix = "technic_cnc_twocurvededge",
model = "technic_two_curved_edge.obj",
desc = S("Two Curved Edge/Corner Block")
},
{suffix = "technic_cnc_spike",
nodebox = cnc_spike(),
desc = S("Spike")},
{ suffix = "technic_cnc_onecurvededge",
model = "technic_one_curved_edge.obj",
desc = S("One Curved Edge Block")
},
{suffix = "technic_cnc_pyramid",
nodebox = cnc_pyramid(),
desc = S("Pyramid")},
{ suffix = "technic_cnc_spike",
model = "technic_pyramid_spike.obj",
desc = S("Spike"),
cbox = {
type = "fixed",
fixed = {
{ -2/16, 4/16, -2/16, 2/16, 8/16, 2/16 },
{ -4/16, 0, -4/16, 4/16, 4/16, 4/16 },
{ -6/16, -4/16, -6/16, 6/16, 0, 6/16 },
{ -8/16, -8/16, -8/16, 8/16, -4/16, 8/16 }
}
}
},
{suffix = "technic_cnc_slope_inner_edge_upsdown",
nodebox = cnc_slope_inner_edge_upsdown(),
desc = S("Slope Upside Down Inner Edge")},
{ suffix = "technic_cnc_pyramid",
model = "technic_pyramid.obj",
desc = S("Pyramid"),
cbox = {
type = "fixed",
fixed = {
{ -2/16, -2/16, -2/16, 2/16, 0, 2/16 },
{ -4/16, -4/16, -4/16, 4/16, -2/16, 4/16 },
{ -6/16, -6/16, -6/16, 6/16, -4/16, 6/16 },
{ -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }
}
}
},
{suffix = "technic_cnc_slope_edge_upsdown",
nodebox = cnc_slope_edge_upsdown(),
desc = S("Slope Upside Down Edge")},
{ suffix = "technic_cnc_slope_inner_edge_upsdown",
model = "technic_innercorner_upsdown.obj",
desc = S("Slope Upside Down Inner Edge/Corner"),
sbox = {
type = "fixed",
fixed = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }
},
cbox = {
type = "fixed",
fixed = {
{ 0.25, -0.25, -0.5, 0.5, -0.5, 0.5 },
{ -0.5, -0.25, 0.25, 0.5, -0.5, 0.5 },
{ 0, 0, -0.5, 0.5, -0.25, 0.5 },
{ -0.5, 0, 0, 0.5, -0.25, 0.5 },
{ -0.25, 0.25, -0.5, 0.5, 0, -0.25 },
{ -0.5, 0.25, -0.25, 0.5, 0, 0.5 },
{ -0.5, 0.5, -0.5, 0.5, 0.25, 0.5 }
}
}
},
{suffix = "technic_cnc_slope_inner_edge",
nodebox = cnc_slope_inner_edge(),
desc = S("Slope Inner Edge")},
{ suffix = "technic_cnc_slope_edge_upsdown",
model = "technic_outercorner_upsdown.obj",
desc = S("Slope Upside Down Outer Edge/Corner"),
cbox = {
type = "fixed",
fixed = {
{ -8/16, 8/16, -8/16, 8/16, 4/16, 8/16 },
{ -4/16, 4/16, -4/16, 8/16, 0, 8/16 },
{ 0, 0, 0, 8/16, -4/16, 8/16 },
{ 4/16, -4/16, 4/16, 8/16, -8/16, 8/16 }
}
}
},
{suffix = "technic_cnc_slope_edge",
nodebox = cnc_slope_edge(),
desc = S("Slope Edge")},
{ suffix = "technic_cnc_slope_inner_edge",
model = "technic_innercorner.obj",
desc = S("Slope Inner Edge/Corner"),
sbox = {
type = "fixed",
fixed = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }
},
cbox = {
type = "fixed",
fixed = {
{ -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 },
{ -0.5, -0.25, -0.25, 0.5, 0, 0.5 },
{ -0.25, -0.25, -0.5, 0.5, 0, -0.25 },
{ -0.5, 0, 0, 0.5, 0.25, 0.5 },
{ 0, 0, -0.5, 0.5, 0.25, 0.5 },
{ -0.5, 0.25, 0.25, 0.5, 0.5, 0.5 },
{ 0.25, 0.25, -0.5, 0.5, 0.5, 0.5 }
}
}
},
{suffix = "technic_cnc_slope_upsdown",
nodebox = cnc_slope_upsdown(),
desc = S("Slope Upside Down")},
{ suffix = "technic_cnc_slope_edge",
model = "technic_outercorner.obj",
desc = S("Slope Outer Edge/Corner"),
cbox = {
type = "fixed",
fixed = {
{ 4/16, 4/16, 4/16, 8/16, 8/16, 8/16 },
{ 0, 0, 0, 8/16, 4/16, 8/16 },
{ -4/16, -4/16, -4/16, 8/16, 0, 8/16 },
{ -8/16, -8/16, -8/16, 8/16, -4/16, 8/16 }
}
}
},
{suffix = "technic_cnc_slope_lying",
nodebox = cnc_slope_lying(),
desc = S("Slope Lying")},
{ suffix = "technic_cnc_slope_upsdown",
model = "technic_slope_upsdown.obj",
desc = S("Slope Upside Down"),
cbox = {
type = "fixed",
fixed = {
{ -8/16, 8/16, -8/16, 8/16, 4/16, 8/16 },
{ -8/16, 4/16, -4/16, 8/16, 0, 8/16 },
{ -8/16, 0, 0, 8/16, -4/16, 8/16 },
{ -8/16, -4/16, 4/16, 8/16, -8/16, 8/16 }
}
}
},
{suffix = "technic_cnc_slope",
nodebox = cnc_slope(),
desc = S("Slope")},
{ suffix = "technic_cnc_slope_lying",
model = "technic_slope_horizontal.obj",
desc = S("Slope Lying"),
cbox = {
type = "fixed",
fixed = {
{ 4/16, -8/16, 4/16, 8/16, 8/16, 8/16 },
{ 0, -8/16, 0, 4/16, 8/16, 8/16 },
{ -4/16, -8/16, -4/16, 0, 8/16, 8/16 },
{ -8/16, -8/16, -8/16, -4/16, 8/16, 8/16 }
}
}
},
{ suffix = "technic_cnc_slope",
model = "technic_slope.obj",
desc = S("Slope"),
cbox = {
type = "fixed",
fixed = {
{ -8/16, 4/16, 4/16, 8/16, 8/16, 8/16 },
{ -8/16, 0, 0, 8/16, 4/16, 8/16 },
{ -8/16, -4/16, -4/16, 8/16, 0, 8/16 },
{ -8/16, -8/16, -8/16, 8/16, -4/16, 8/16 }
}
}
},
}
-- Allow disabling certain programs for some node. Default is allowing all types for all nodes
technic.cnc.programs_disable = {
-- ["default:brick"] = {"technic_cnc_stick"}, -- Example: Disallow the stick for brick
-- ...
["default:dirt"] = {"technic_cnc_sphere", "technic_cnc_slope_upsdown", "technic_cnc_edge",
["default:dirt"] = {"technic_cnc_oblate_spheroid", "technic_cnc_slope_upsdown", "technic_cnc_edge",
"technic_cnc_inner_edge", "technic_cnc_slope_edge_upsdown",
"technic_cnc_slope_inner_edge_upsdown", "technic_cnc_stick",
"technic_cnc_cylinder_horizontal"}
}
-- Generic function for registering all the different node types
function technic.cnc.register_program(recipeitem, suffix, nodebox, groups, images, description)
function technic.cnc.register_program(recipeitem, suffix, model, groups, images, description, cbox, sbox)
local dtype
local nodeboxdef
local meshdef
if type(model) ~= "string" then -- assume a nodebox if it's a table or function call
dtype = "nodebox"
nodeboxdef = {
type = "fixed",
fixed = model
}
else
dtype = "mesh"
meshdef = model
end
if cbox and not sbox then sbox = cbox end
minetest.register_node(":"..recipeitem.."_"..suffix, {
description = description,
drawtype = "nodebox",
drawtype = dtype,
node_box = nodeboxdef,
mesh = meshdef,
tiles = images,
paramtype = "light",
paramtype2 = "facedir",
walkable = true,
node_box = {
type = "fixed",
fixed = nodebox
},
groups = groups,
selection_box = sbox,
collision_box = cbox
})
end
@ -309,7 +321,8 @@ function technic.cnc.register_all(recipeitem, groups, images, description)
end
-- Create the node if it passes the test
if do_register then
technic.cnc.register_program(recipeitem, data.suffix, data.nodebox, groups, images, description.." "..data.desc)
technic.cnc.register_program(recipeitem, data.suffix, data.model,
groups, images, description.." "..data.desc, data.cbox, data.sbox)
end
end
end
@ -317,7 +330,7 @@ end
-- REGISTER NEW TECHNIC_CNC_API's PART 2: technic.cnc..register_element_end(subname, recipeitem, groups, images, desc_element_xyz)
-----------------------------------------------------------------------------------------------------------------------
function technic.cnc.register_slope_edge_etc(recipeitem, groups, images, desc_slope, desc_slope_lying, desc_slope_upsdown, desc_slope_edge, desc_slope_inner_edge, desc_slope_upsdwn_edge, desc_slope_upsdwn_inner_edge, desc_pyramid, desc_spike, desc_onecurvededge, desc_twocurvededge, desc_cylinder, desc_cylinder_horizontal, desc_sphere, desc_element_straight, desc_element_edge, desc_element_t, desc_element_cross, desc_element_end)
function technic.cnc.register_slope_edge_etc(recipeitem, groups, images, desc_slope, desc_slope_lying, desc_slope_upsdown, desc_slope_edge, desc_slope_inner_edge, desc_slope_upsdwn_edge, desc_slope_upsdwn_inner_edge, desc_pyramid, desc_spike, desc_onecurvededge, desc_twocurvededge, desc_cylinder, desc_cylinder_horizontal, desc_spheroid, desc_element_straight, desc_element_edge, desc_element_t, desc_element_cross, desc_element_end)
technic.cnc.register_slope(recipeitem, groups, images, desc_slope)
technic.cnc.register_slope_lying(recipeitem, groups, images, desc_slope_lying)
@ -332,7 +345,7 @@ function technic.cnc.register_slope_edge_etc(recipeitem, groups, images, desc_sl
technic.cnc.register_twocurvededge(recipeitem, groups, images, desc_twocurvededge)
technic.cnc.register_cylinder(recipeitem, groups, images, desc_cylinder)
technic.cnc.register_cylinder_horizontal(recipeitem, groups, images, desc_cylinder_horizontal)
technic.cnc.register_sphere(recipeitem, groups, images, desc_sphere)
technic.cnc.register_spheroid(recipeitem, groups, images, desc_spheroid)
technic.cnc.register_element_straight(recipeitem, groups, images, desc_element_straight)
technic.cnc.register_element_edge(recipeitem, groups, images, desc_element_edge)
technic.cnc.register_element_t(recipeitem, groups, images, desc_element_t)

View File

@ -9,11 +9,6 @@ technic.cnc.register_all("default:dirt",
{snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1},
{"default_grass.png", "default_dirt.png", "default_grass.png"},
S("Dirt"))
technic.cnc.programs_disable["default:dirt"] = {"technic_cnc_sphere", "technic_cnc_slope_upsdown",
"technic_cnc_edge", "technic_cnc_inner_edge",
"technic_cnc_slope_edge_upsdown", "technic_cnc_slope_inner_edge_upsdown",
"technic_cnc_stick", "technic_cnc_cylinder_horizontal"}
-- WOOD
-------
technic.cnc.register_all("default:wood",
@ -42,7 +37,7 @@ technic.cnc.register_all("default:brick",
-- SANDSTONE
------------
technic.cnc.register_all("default:sandstone",
{crumbly=2, cracky=2, not_in_creative_inventory=1},
{crumbly=2, cracky=3, not_in_creative_inventory=1},
{"default_sandstone.png"},
S("Sandstone"))
@ -90,7 +85,7 @@ technic.cnc.register_all("technic:marble",
-- Granite
------------
technic.cnc.register_all("technic:granite",
{cracky=3, not_in_creative_inventory=1},
{cracky=1, not_in_creative_inventory=1},
{"technic_granite.png"},
S("Granite"))

View File

@ -4,9 +4,9 @@ minetest.register_alias("compressor", "technic:lv_compressor")
minetest.register_craft({
output = 'technic:lv_compressor',
recipe = {
{'default:stone', 'default:stone', 'default:stone'},
{'mesecons:piston', 'technic:motor', 'mesecons:piston'},
{'default:stone', 'technic:lv_cable0', 'default:stone'},
{'default:stone', 'technic:motor', 'default:stone'},
{'mesecons:piston', 'technic:machine_casing', 'mesecons:piston'},
{'technic:fine_silver_wire', 'technic:lv_cable', 'technic:fine_silver_wire'},
}
})

View File

@ -5,9 +5,9 @@
minetest.register_craft({
output = 'technic:electric_furnace',
recipe = {
{'default:cobble', 'default:cobble', 'default:cobble'},
{'default:cobble', '', 'default:cobble'},
{'technic:cast_iron_ingot', 'moreores:copper_ingot', 'technic:cast_iron_ingot'},
{'default:cobble', 'default:cobble', 'default:cobble'},
{'default:cobble', 'technic:machine_casing', 'default:cobble'},
{'default:cobble', 'technic:lv_cable', 'default:cobble'},
}
})

View File

@ -4,9 +4,9 @@ minetest.register_alias("extractor", "technic:lv_extractor")
minetest.register_craft({
output = 'technic:lv_extractor',
recipe = {
{'technic:treetap', 'technic:motor', 'technic:treetap'},
{'technic:treetap', 'technic:lv_cable0', 'technic:treetap'},
{'', '', ''},
{'technic:treetap', 'technic:motor', 'technic:treetap'},
{'technic:treetap', 'technic:machine_casing', 'technic:treetap'},
{'', 'technic:lv_cable', ''},
}
})

View File

@ -8,9 +8,9 @@ minetest.register_alias("lv_generator", "technic:lv_generator")
minetest.register_craft({
output = 'technic:lv_generator',
recipe = {
{'default:stone', 'default:stone', 'default:stone'},
{'default:stone', '', 'default:stone'},
{'default:stone', 'default:copper_ingot', 'default:stone'},
{'default:stone', 'default:furnace', 'default:stone'},
{'default:stone', 'technic:machine_casing', 'default:stone'},
{'default:stone', 'technic:lv_cable', 'default:stone'},
}
})

View File

@ -10,9 +10,9 @@ local S = technic.getter
minetest.register_craft({
output = 'technic:geothermal',
recipe = {
{'default:stone', 'default:stone', 'default:stone'},
{'default:copper_ingot', 'default:diamond', 'default:copper_ingot'},
{'default:stone', 'default:copper_ingot', 'default:stone'},
{'technic:granite', 'default:diamond', 'technic:granite'},
{'technic:fine_copper_wire', 'technic:machine_casing', 'technic:fine_copper_wire'},
{'technic:granite', 'technic:lv_cable', 'technic:granite'},
}
})
@ -20,32 +20,6 @@ minetest.register_craftitem("technic:geothermal", {
description = S("Geothermal %s Generator"):format("LV"),
})
minetest.register_node("technic:geothermal", {
description = S("Geothermal %s Generator"):format("LV"),
tiles = {"technic_geothermal_top.png", "technic_machine_bottom.png", "technic_geothermal_side.png",
"technic_geothermal_side.png", "technic_geothermal_side.png", "technic_geothermal_side.png"},
paramtype2 = "facedir",
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Geothermal %s Generator"):format("LV"))
meta:set_int("LV_EU_supply", 0)
end,
})
minetest.register_node("technic:geothermal_active", {
description = S("Geothermal %s Generator"):format("LV"),
tiles = {"technic_geothermal_top_active.png", "technic_machine_bottom.png", "technic_geothermal_side.png",
"technic_geothermal_side.png", "technic_geothermal_side.png", "technic_geothermal_side.png"},
paramtype2 = "facedir",
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, not_in_creative_inventory=1},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
drop = "technic:geothermal",
})
local check_node_around = function(pos)
local node = minetest.get_node(pos)
if node.name == "default:water_source" or node.name == "default:water_flowing" then return 1 end
@ -53,61 +27,86 @@ local check_node_around = function(pos)
return 0
end
minetest.register_abm({
nodenames = {"technic:geothermal","technic:geothermal_active"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local water_nodes = 0
local lava_nodes = 0
local production_level = 0
local eu_supply = 0
local run = function(pos, node)
local meta = minetest.get_meta(pos)
local water_nodes = 0
local lava_nodes = 0
local production_level = 0
local eu_supply = 0
-- Correct positioning is water on one side and lava on the other.
-- The two cannot be adjacent because the lava the turns into obsidian or rock.
-- To get to 100% production stack the water and lava one extra block down as well:
-- WGL (W=Water, L=Lava, G=the generator, |=an LV cable)
-- W|L
-- Correct positioning is water on one side and lava on the other.
-- The two cannot be adjacent because the lava the turns into obsidian or rock.
-- To get to 100% production stack the water and lava one extra block down as well:
-- WGL (W=Water, L=Lava, G=the generator, |=an LV cable)
-- W|L
local positions = {
{x=pos.x+1, y=pos.y, z=pos.z},
{x=pos.x+1, y=pos.y-1, z=pos.z},
{x=pos.x-1, y=pos.y, z=pos.z},
{x=pos.x-1, y=pos.y-1, z=pos.z},
{x=pos.x, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y-1, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1},
{x=pos.x, y=pos.y-1, z=pos.z-1},
}
for _, p in pairs(positions) do
local check = check_node_around(p)
if check == 1 then water_nodes = water_nodes + 1 end
if check == 2 then lava_nodes = lava_nodes + 1 end
end
if water_nodes == 1 and lava_nodes == 1 then production_level = 25; eu_supply = 50 end
if water_nodes == 2 and lava_nodes == 1 then production_level = 50; eu_supply = 100 end
if water_nodes == 1 and lava_nodes == 2 then production_level = 75; eu_supply = 200 end
if water_nodes == 2 and lava_nodes == 2 then production_level = 100; eu_supply = 300 end
if production_level > 0 then
meta:set_int("LV_EU_supply", eu_supply)
end
meta:set_string("infotext",
S("Geothermal %s Generator"):format("LV").." ("..production_level.."%)")
if production_level > 0 and minetest.get_node(pos).name == "technic:geothermal" then
technic.swap_node (pos, "technic:geothermal_active")
return
end
if production_level == 0 then
technic.swap_node(pos, "technic:geothermal")
meta:set_int("LV_EU_supply", 0)
end
local positions = {
{x=pos.x+1, y=pos.y, z=pos.z},
{x=pos.x+1, y=pos.y-1, z=pos.z},
{x=pos.x-1, y=pos.y, z=pos.z},
{x=pos.x-1, y=pos.y-1, z=pos.z},
{x=pos.x, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y-1, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1},
{x=pos.x, y=pos.y-1, z=pos.z-1},
}
for _, p in pairs(positions) do
local check = check_node_around(p)
if check == 1 then water_nodes = water_nodes + 1 end
if check == 2 then lava_nodes = lava_nodes + 1 end
end
})
if water_nodes == 1 and lava_nodes == 1 then production_level = 25; eu_supply = 50 end
if water_nodes == 2 and lava_nodes == 1 then production_level = 50; eu_supply = 100 end
if water_nodes == 1 and lava_nodes == 2 then production_level = 75; eu_supply = 200 end
if water_nodes == 2 and lava_nodes == 2 then production_level = 100; eu_supply = 300 end
if production_level > 0 then
meta:set_int("LV_EU_supply", eu_supply)
end
meta:set_string("infotext",
S("Geothermal %s Generator"):format("LV").." ("..production_level.."%)")
if production_level > 0 and minetest.get_node(pos).name == "technic:geothermal" then
technic.swap_node (pos, "technic:geothermal_active")
return
end
if production_level == 0 then
technic.swap_node(pos, "technic:geothermal")
meta:set_int("LV_EU_supply", 0)
end
end
minetest.register_node("technic:geothermal", {
description = S("Geothermal %s Generator"):format("LV"),
tiles = {"technic_geothermal_top.png", "technic_machine_bottom.png", "technic_geothermal_side.png",
"technic_geothermal_side.png", "technic_geothermal_side.png", "technic_geothermal_side.png"},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_lv=1},
paramtype2 = "facedir",
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Geothermal %s Generator"):format("LV"))
meta:set_int("LV_EU_supply", 0)
end,
technic_run = run,
})
minetest.register_node("technic:geothermal_active", {
description = S("Geothermal %s Generator"):format("LV"),
tiles = {"technic_geothermal_top_active.png", "technic_machine_bottom.png", "technic_geothermal_side.png",
"technic_geothermal_side.png", "technic_geothermal_side.png", "technic_geothermal_side.png"},
paramtype2 = "facedir",
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_lv=1, not_in_creative_inventory=1},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
drop = "technic:geothermal",
technic_run = run,
})
technic.register_machine("LV", "technic:geothermal", technic.producer)
technic.register_machine("LV", "technic:geothermal_active", technic.producer)

View File

@ -1,11 +1,11 @@
minetest.register_alias("grinder", "technic:grinder")
minetest.register_alias("grinder", "technic:lv_grinder")
minetest.register_craft({
output = 'technic:grinder',
output = 'technic:lv_grinder',
recipe = {
{'default:desert_stone', 'default:desert_stone', 'default:desert_stone'},
{'default:desert_stone', 'default:diamond', 'default:desert_stone'},
{'default:stone', 'moreores:copper_ingot', 'default:stone'},
{'default:desert_stone', 'default:diamond', 'default:desert_stone'},
{'default:desert_stone', 'technic:machine_casing', 'default:desert_stone'},
{'technic:granite', 'technic:lv_cable', 'technic:granite'},
}
})

View File

@ -14,10 +14,6 @@ dofile(path.."/geothermal.lua")
dofile(path.."/water_mill.lua")
dofile(path.."/generator.lua")
-- Coal-powered machines (TODO -> move to somewhere else?)
dofile(path.."/coal_alloy_furnace.lua")
dofile(path.."/coal_furnace.lua")
-- Machines
dofile(path.."/alloy_furnace.lua")
dofile(path.."/electric_furnace.lua")

View File

@ -7,142 +7,125 @@ minetest.register_alias("music_player", "technic:music_player")
minetest.register_craft({
output = 'technic:music_player',
recipe = {
{'group:wood', 'group:wood', 'group:wood'},
{'default:diamond', 'default:diamond', 'default:diamond'},
{'default:stone', 'default:copper_ingot', 'default:stone'},
{'technic:chromium_ingot', 'default:diamond', 'technic:chromium_ingot'},
{'default:diamond', 'technic:machine_casing', 'default:diamond'},
{'default:mossycobble', 'technic:lv_cable', 'default:mossycobble'},
}
})
local music_handles = {}
local music_player_formspec =
"invsize[8,9;]"..
"label[0,0;"..S("%s Music Player"):format("LV").."]"..
"button[4,1;1,1;track1;1]"..
"button[5,1;1,1;track2;2]"..
"button[6,1;1,1;track3;3]"..
"button[4,2;1,1;track4;4]"..
"button[5,2;1,1;track5;5]"..
"button[6,2;1,1;track6;6]"..
"button[4,3;1,1;track7;7]"..
"button[5,3;1,1;track8;8]"..
"button[6,3;1,1;track9;9]"..
"button[4,4;1,2;play;Play]"..
"button[6,4;1,2;stop;Stop]"..
"label[4,0;"..S("Current track %s"):format("--").."]"
local function play_track(pos, track)
return minetest.sound_play("technic_track"..tostring(track),
{pos = pos, gain = 1.0, loop = true, max_hear_distance = 72,})
end
local run = function(pos, node)
local meta = minetest.get_meta(pos)
local eu_input = meta:get_int("LV_EU_input")
local machine_name = S("%s Music Player"):format("LV")
local machine_node = "technic:music_player"
local demand = 150
local current_track = meta:get_int("current_track")
local pos_hash = minetest.hash_node_position(pos)
local music_handle = music_handles[pos_hash]
-- Setup meta data if it does not exist.
if not eu_input then
meta:set_int("LV_EU_demand", demand)
meta:set_int("LV_EU_input", 0)
return
end
if meta:get_int("active") == 0 then
meta:set_string("infotext", S("%s Idle"):format(machine_name))
meta:set_int("LV_EU_demand", 0)
return
end
if eu_input < demand then
meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
if music_handle then
minetest.sound_stop(music_handle)
music_handle = nil
end
elseif eu_input >= demand then
meta:set_string("infotext", S("%s Active"):format(machine_name))
if not music_handle then
music_handle = play_track(pos, current_track)
end
end
music_handles[pos_hash] = music_handle
meta:set_int("LV_EU_demand", demand)
end
local function stop_player(pos, node)
local pos_hash = minetest.hash_node_position(pos)
local music_handle = music_handles[pos_hash]
if music_handle then
minetest.sound_stop(music_handle)
music_handles[pos_hash] = nil
end
end
local function set_display(meta)
meta:set_string("formspec",
"size[4,4.5]"..
"item_image[0,0;1,1;technic:music_player]"..
"label[1,0;"..S("%s Music Player"):format("LV").."]"..
"button[0,1;1,1;track1;1]"..
"button[1,1;1,1;track2;2]"..
"button[2,1;1,1;track3;3]"..
"button[0,2;1,1;track4;4]"..
"button[1,2;1,1;track5;5]"..
"button[2,2;1,1;track6;6]"..
"button[0,3;1,1;track7;7]"..
"button[1,3;1,1;track8;8]"..
"button[2,3;1,1;track9;9]"..
"button[3,1;1,1;stop;Stop]"..
"label[0,4;"..minetest.formspec_escape(
meta:get_int("active") == 0 and
S("Stopped") or
S("Current track %s"):format(meta:get_int("current_track"))).."]")
end
minetest.register_node("technic:music_player", {
description = S("%s Music Player"):format("LV"),
tiles = {"technic_music_player_top.png", "technic_machine_bottom.png", "technic_music_player_side.png",
"technic_music_player_side.png", "technic_music_player_side.png", "technic_music_player_side.png"},
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_lv=1},
connect_sides = {"bottom"},
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("%s Music Player"):format("LV"))
meta:set_int("active", 0)
meta:set_int("current_track", 1)
meta:set_string("formspec", music_player_formspec)
set_display(meta)
end,
on_receive_fields = function(pos, formanme, fields, sender)
local meta = minetest.get_meta(pos)
local pos_hash = minetest.hash_node_position(pos)
local music_handle = music_handles[pos_hash]
local current_track = meta:get_int("current_track")
if fields.track1 then current_track = 1 end
if fields.track2 then current_track = 2 end
if fields.track3 then current_track = 3 end
if fields.track4 then current_track = 4 end
if fields.track5 then current_track = 5 end
if fields.track6 then current_track = 6 end
if fields.track7 then current_track = 7 end
if fields.track8 then current_track = 8 end
if fields.track9 then current_track = 9 end
meta:set_int("current_track", current_track)
meta:set_string("formspec",
"invsize[8,9;]"..
"label[0,0;"..S("%s Music Player"):format("LV").."]"..
"button[4,1;1,1;track1;1]"..
"button[5,1;1,1;track2;2]"..
"button[6,1;1,1;track3;3]"..
"button[4,2;1,1;track4;4]"..
"button[5,2;1,1;track5;5]"..
"button[6,2;1,1;track6;6]"..
"button[4,3;1,1;track7;7]"..
"button[5,3;1,1;track8;8]"..
"button[6,3;1,1;track9;9]"..
"button[4,4;1,2;play;Play]"..
"button[6,4;1,2;stop;Stop]"..
"label[4,0;"..S("Current track %s")
:format(current_track).."]")
if fields.play then
if music_handle then
minetest.sound_stop(music_handle)
end
music_handle = play_track(pos, current_track)
meta:set_int("active", 1)
local new_track = nil
if fields.stop then new_track = 0 end
if fields.track1 then new_track = 1 end
if fields.track2 then new_track = 2 end
if fields.track3 then new_track = 3 end
if fields.track4 then new_track = 4 end
if fields.track5 then new_track = 5 end
if fields.track6 then new_track = 6 end
if fields.track7 then new_track = 7 end
if fields.track8 then new_track = 8 end
if fields.track9 then new_track = 9 end
if new_track then
stop_player(pos)
local meta = minetest.get_meta(pos)
meta:set_int("active", new_track == 0 and 0 or 1)
meta:set_int("current_track", new_track)
set_display(meta)
end
if fields.stop then
meta:set_int("active", 0)
if music_handle then
minetest.sound_stop(music_handle)
end
end
music_handles[pos_hash] = music_handle
end,
})
minetest.register_abm({
nodenames = {"technic:music_player"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local eu_input = meta:get_int("LV_EU_input")
local machine_name = S("%s Music Player"):format("LV")
local machine_node = "technic:music_player"
local demand = 150
local current_track = meta:get_int("current_track")
local pos_hash = minetest.hash_node_position(pos)
local music_handle = music_handles[pos_hash]
-- Setup meta data if it does not exist.
if not eu_input then
meta:set_int("LV_EU_demand", demand)
meta:set_int("LV_EU_input", 0)
return
end
-- Power off automatically if no longer connected to a switching station
technic.switching_station_timeout_count(pos, "LV")
if meta:get_int("active") == 0 then
meta:set_string("infotext", S("%s Idle"):format(machine_name))
meta:set_int("LV_EU_demand", 0)
return
end
if eu_input < demand then
meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
if music_handle then
minetest.sound_stop(music_handle)
music_handle = nil
end
elseif eu_input >= demand then
meta:set_string("infotext", S("%s Active"):format(machine_name))
if not music_handle then
music_handle = play_track(pos, current_track)
end
end
music_handles[pos_hash] = music_handle
meta:set_int("LV_EU_demand", demand)
end
on_destruct = stop_player,
technic_run = run,
technic_on_disable = stop_player,
})
technic.register_machine("LV", "technic:music_player", technic.receiver)

View File

@ -10,7 +10,7 @@ minetest.register_craft({
recipe = {
{'technic:solar_panel', 'technic:solar_panel', 'technic:solar_panel'},
{'technic:carbon_steel_ingot', 'technic:lv_transformer', 'technic:carbon_steel_ingot'},
{'', 'technic:lv_cable0', ''},
{'', 'technic:lv_cable', ''},
}
})

View File

@ -4,16 +4,58 @@
local S = technic.getter
minetest.register_craft({
output = 'technic:solar_panel',
recipe = {
{'technic:doped_silicon_wafer', 'technic:doped_silicon_wafer', 'technic:doped_silicon_wafer'},
{'technic:fine_silver_wire', 'technic:lv_cable', 'mesecons_materials:glue'},
}
})
local run = function(pos, node)
-- The action here is to make the solar panel prodice power
-- Power is dependent on the light level and the height above ground
-- There are many ways to cheat by using other light sources like lamps.
-- As there is no way to determine if light is sunlight that is just a shame.
-- To take care of some of it solar panels do not work outside daylight hours or if
-- built below 0m
local pos1 = {x=pos.x, y=pos.y+1, z=pos.z}
local machine_name = S("Small Solar %s Generator"):format("LV")
local light = minetest.get_node_light(pos1, nil)
local time_of_day = minetest.get_timeofday()
local meta = minetest.get_meta(pos)
if light == nil then light = 0 end
-- turn on panel only during day time and if sufficient light
-- I know this is counter intuitive when cheating by using other light sources underground.
if light >= 12 and time_of_day >= 0.24 and time_of_day <= 0.76 and pos.y > -10 then
local charge_to_give = math.floor((light + pos1.y) * 3)
charge_to_give = math.max(charge_to_give, 0)
charge_to_give = math.min(charge_to_give, 200)
meta:set_string("infotext", S("@1 Active (@2)", machine_name,
technic.EU_string(charge_to_give)))
meta:set_int("LV_EU_supply", charge_to_give)
else
meta:set_string("infotext", S("%s Idle"):format(machine_name))
meta:set_int("LV_EU_supply", 0)
end
end
minetest.register_node("technic:solar_panel", {
tiles = {"technic_solar_panel_top.png", "technic_solar_panel_bottom.png", "technic_solar_panel_side.png",
"technic_solar_panel_side.png", "technic_solar_panel_side.png", "technic_solar_panel_side.png"},
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_lv=1},
connect_sides = {"bottom"},
sounds = default.node_sound_wood_defaults(),
description = S("Small Solar %s Generator"):format("LV"),
active = false,
drawtype = "nodebox",
paramtype = "light",
is_ground_content = true,
is_ground_content = true,
node_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
@ -23,51 +65,8 @@ minetest.register_node("technic:solar_panel", {
meta:set_int("LV_EU_supply", 0)
meta:set_string("infotext", S("Small Solar %s Generator"):format("LV"))
end,
technic_run = run,
})
minetest.register_craft({
output = 'technic:solar_panel',
recipe = {
{'technic:doped_silicon_wafer', 'technic:doped_silicon_wafer', 'technic:doped_silicon_wafer'},
{'technic:wrought_iron_ingot', 'technic:lv_cable0', 'technic:wrought_iron_ingot'},
}
})
minetest.register_abm({
nodenames = {"technic:solar_panel"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
-- The action here is to make the solar panel prodice power
-- Power is dependent on the light level and the height above ground
-- 130m and above is optimal as it would be above cloud level.
-- Height gives 1/4 of the effect, light 3/4. Max. effect is 26EU.
-- There are many ways to cheat by using other light sources like lamps.
-- As there is no way to determine if light is sunlight that is just a shame.
-- To take care of some of it solar panels do not work outside daylight hours or if
-- built below -10m
local pos1 = {x=pos.x, y=pos.y+1, z=pos.z}
local machine_name = S("Small Solar %s Generator"):format("LV")
local light = minetest.get_node_light(pos1, nil)
local time_of_day = minetest.get_timeofday()
local meta = minetest.get_meta(pos)
if light == nil then light = 0 end
-- turn on panel only during day time and if sufficient light
-- I know this is counter intuitive when cheating by using other light sources underground.
if light >= 12 and time_of_day >= 0.24 and time_of_day <= 0.76 and pos.y > -10 then
local charge_to_give = math.floor((light + pos1.y) * 3)
charge_to_give = math.max(charge_to_give, 0)
charge_to_give = math.min(charge_to_give, 200)
meta:set_string("infotext", S("%s Active"):format(machine_name).." ("..charge_to_give.."EU)")
meta:set_int("LV_EU_supply", charge_to_give)
else
meta:set_string("infotext", S("%s Idle"):format(machine_name))
meta:set_int("LV_EU_supply", 0)
end
end,
})
technic.register_machine("LV", "technic:solar_panel", technic.producer)

View File

@ -1,34 +1,92 @@
-- A water mill produces LV EUs by exploiting flowing water across it
-- It is a LV EU supplyer and fairly low yield (max 120EUs)
-- It is a little under half as good as the thermal generator.
-- It is a LV EU supplyer and fairly low yield (max 180EUs)
-- It is a little over half as good as the thermal generator.
local S = technic.getter
local cable_entry = "^technic_cable_connection_overlay.png"
minetest.register_alias("water_mill", "technic:water_mill")
minetest.register_craft({
output = 'technic:water_mill',
recipe = {
{'default:stone', 'default:stone', 'default:stone'},
{'group:wood', 'default:diamond', 'group:wood'},
{'default:stone', 'default:copper_ingot', 'default:stone'},
{'technic:marble', 'default:diamond', 'technic:marble'},
{'group:wood', 'technic:machine_casing', 'group:wood'},
{'technic:marble', 'technic:lv_cable', 'technic:marble'},
}
})
local function check_node_around_mill(pos)
local node = minetest.get_node(pos)
if node.name == "default:water_flowing"
or node.name == "default:river_water_flowing" then
return node.param2 -- returns approx. water flow, if any
end
return false
end
local run = function(pos, node)
local meta = minetest.get_meta(pos)
local water_flow = 0
local production_level = 0
local eu_supply = 0
local max_output = 4 * 45 -- keeping it around 180, little more than previous 150 :)
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, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1},
}
for _, p in pairs(positions) do
local check = check_node_around_mill(p)
if check then
water_flow = water_flow + check
end
end
eu_supply = math.min(4 * water_flow, max_output)
production_level = math.floor(100 * eu_supply / max_output)
meta:set_int("LV_EU_supply", eu_supply)
meta:set_string("infotext",
S("Hydro %s Generator"):format("LV").." ("..production_level.."%)")
if production_level > 0 and
minetest.get_node(pos).name == "technic:water_mill" then
technic.swap_node (pos, "technic:water_mill_active")
meta:set_int("LV_EU_supply", 0)
return
end
if production_level == 0 then
technic.swap_node(pos, "technic:water_mill")
end
end
minetest.register_node("technic:water_mill", {
description = S("Hydro %s Generator"):format("LV"),
tiles = {"technic_water_mill_top.png", "technic_machine_bottom.png",
"technic_water_mill_side.png", "technic_water_mill_side.png",
"technic_water_mill_side.png", "technic_water_mill_side.png"},
tiles = {
"technic_water_mill_top.png",
"technic_machine_bottom.png"..cable_entry,
"technic_water_mill_side.png",
"technic_water_mill_side.png",
"technic_water_mill_side.png",
"technic_water_mill_side.png"
},
paramtype2 = "facedir",
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_lv=1},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Hydro %s Generator"):format("LV"))
meta:set_int("LV_EU_supply", 0)
end,
end,
technic_run = run,
})
minetest.register_node("technic:water_mill_active", {
@ -37,68 +95,15 @@ minetest.register_node("technic:water_mill_active", {
"technic_water_mill_side.png", "technic_water_mill_side.png",
"technic_water_mill_side.png", "technic_water_mill_side.png"},
paramtype2 = "facedir",
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, not_in_creative_inventory=1},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_lv=1, not_in_creative_inventory=1},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
drop = "technic:water_mill",
technic_run = run,
technic_disabled_machine_name = "technic:water_mill",
})
local function check_node_around_mill(pos)
local node = minetest.get_node(pos)
if node.name == "default:water_flowing" or
node.name == "default:water_source" then
return true
end
return false
end
minetest.register_abm({
nodenames = {"technic:water_mill", "technic:water_mill_active"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local water_nodes = 0
local lava_nodes = 0
local production_level = 0
local eu_supply = 0
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, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1},
}
for _, p in pairs(positions) do
local check = check_node_around_mill(p)
if check then
water_nodes = water_nodes + 1
end
end
production_level = 25 * water_nodes
eu_supply = 30 * water_nodes
if production_level > 0 then
meta:set_int("LV_EU_supply", eu_supply)
end
meta:set_string("infotext",
S("Hydro %s Generator"):format("LV").." ("..production_level.."%)")
if production_level > 0 and
minetest.get_node(pos).name == "technic:water_mill" then
technic.swap_node (pos, "technic:water_mill_active")
meta:set_int("LV_EU_supply", 0)
return
end
if production_level == 0 then
technic.swap_node(pos, "technic:water_mill")
end
end
})
technic.register_machine("LV", "technic:water_mill", technic.producer)
technic.register_machine("LV", "technic:water_mill_active", technic.producer)

View File

@ -5,7 +5,7 @@ minetest.register_craft({
recipe = {
{'technic:stainless_steel_ingot', 'technic:lv_alloy_furnace', 'technic:stainless_steel_ingot'},
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
{'technic:stainless_steel_ingot', 'technic:mv_cable0', 'technic:stainless_steel_ingot'},
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
}
})

View File

@ -5,7 +5,7 @@ minetest.register_craft({
recipe = {
{'technic:lv_battery_box0', 'technic:lv_battery_box0', 'technic:lv_battery_box0'},
{'technic:lv_battery_box0', 'technic:mv_transformer', 'technic:lv_battery_box0'},
{'', 'technic:mv_cable0', ''},
{'', 'technic:mv_cable', ''},
}
})

View File

@ -1,12 +1,12 @@
minetest.register_alias("mv_cable", "technic:mv_cable0")
minetest.register_alias("mv_cable", "technic:mv_cable")
minetest.register_craft({
output = 'technic:mv_cable0 3',
output = 'technic:mv_cable 3',
recipe ={
{'technic:rubber', 'technic:rubber', 'technic:rubber'},
{'technic:lv_cable0', 'technic:lv_cable0', 'technic:lv_cable0'},
{'technic:rubber', 'technic:rubber', 'technic:rubber'},
{'technic:rubber', 'technic:rubber', 'technic:rubber'},
{'technic:lv_cable', 'technic:lv_cable', 'technic:lv_cable'},
{'technic:rubber', 'technic:rubber', 'technic:rubber'},
}
})

View File

@ -0,0 +1,16 @@
minetest.register_craft({
output = "technic:mv_centrifuge",
recipe = {
{"technic:motor", "technic:copper_plate", "technic:diamond_drill_head"},
{"technic:copper_plate", "technic:machine_casing", "technic:copper_plate" },
{"pipeworks:one_way_tube", "technic:mv_cable", "pipeworks:mese_filter" },
}
})
technic.register_centrifuge({
tier = "MV",
demand = { 8000, 7000, 6000 },
speed = 2,
upgrade = 1,
tube = 1,
})

View File

@ -5,7 +5,7 @@ minetest.register_craft({
recipe = {
{'technic:stainless_steel_ingot', 'technic:lv_compressor', 'technic:stainless_steel_ingot'},
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
{'technic:stainless_steel_ingot', 'technic:mv_cable0', 'technic:stainless_steel_ingot'},
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
}
})

View File

@ -9,8 +9,8 @@ minetest.register_craft({
output = 'technic:mv_electric_furnace',
recipe = {
{'technic:stainless_steel_ingot', 'technic:lv_electric_furnace', 'technic:stainless_steel_ingot'},
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
{'technic:stainless_steel_ingot', 'technic:mv_cable0', 'technic:stainless_steel_ingot'},
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
}
})

View File

@ -5,7 +5,7 @@ minetest.register_craft({
recipe = {
{'technic:stainless_steel_ingot', 'technic:lv_extractor', 'technic:stainless_steel_ingot'},
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
{'technic:stainless_steel_ingot', 'technic:mv_cable0', 'technic:stainless_steel_ingot'},
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
}
})

View File

@ -4,7 +4,7 @@ minetest.register_craft({
output = 'technic:mv_generator',
recipe = {
{'technic:stainless_steel_ingot', 'technic:lv_generator', 'technic:stainless_steel_ingot'},
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
}
})

View File

@ -4,8 +4,8 @@ minetest.register_craft({
output = 'technic:mv_grinder',
recipe = {
{'technic:stainless_steel_ingot', 'technic:lv_grinder', 'technic:stainless_steel_ingot'},
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
{'technic:stainless_steel_ingot', 'technic:mv_cable0', 'technic:stainless_steel_ingot'},
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
}
})

View File

@ -0,0 +1,105 @@
-- A Hydro Turbine produces MV EUs by exploiting flowing water across it
-- It is a MV EU supplyer and fairly high yield (max 1800EUs)
local S = technic.getter
local cable_entry = "^technic_cable_connection_overlay.png"
minetest.register_alias("hydro_turbine", "technic:hydro_turbine")
minetest.register_craft({
output = 'technic:hydro_turbine',
recipe = {
{'technic:stainless_steel_ingot', 'technic:water_mill', 'technic:stainless_steel_ingot'},
{'technic:water_mill', 'technic:mv_transformer', 'technic:water_mill'},
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
}
})
local function get_water_flow(pos)
local node = minetest.get_node(pos)
if minetest.get_item_group(node.name, "water") == 3 then
return node.param2 -- returns approx. water flow, if any
end
return 0
end
---
-- 10 times better than LV hydro because of 2 extra water mills and 4 stainless steel, a transformer and whatnot ;P.
-- Man hydro turbines are tough and long lasting. So, give it some value :)
local run = function(pos, node)
local meta = minetest.get_meta(pos)
local water_flow = 0
local production_level = 0
local eu_supply = 0
local max_output = 40 * 45 -- Generates 1800EU/s
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, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1},
}
for _, p in pairs(positions) do
water_flow = water_flow + get_water_flow(p)
end
eu_supply = math.min(40 * water_flow, max_output)
production_level = math.floor(100 * eu_supply / max_output)
meta:set_int("MV_EU_supply", eu_supply)
meta:set_string("infotext",
S("Hydro %s Generator"):format("MV").." ("..production_level.."%)")
if production_level > 0 and
minetest.get_node(pos).name == "technic:hydro_turbine" then
technic.swap_node(pos, "technic:hydro_turbine_active")
meta:set_int("MV_EU_supply", 0)
return
end
if production_level == 0 then
technic.swap_node(pos, "technic:hydro_turbine")
end
end
minetest.register_node("technic:hydro_turbine", {
description = S("Hydro %s Generator"):format("MV"),
tiles = {
"technic_hydro_turbine_top.png",
"technic_machine_bottom.png"..cable_entry,
"technic_hydro_turbine_side.png",
"technic_hydro_turbine_side.png",
"technic_hydro_turbine_side.png",
"technic_hydro_turbine_side.png"
},
paramtype2 = "facedir",
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_mv=1},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Hydro %s Generator"):format("MV"))
meta:set_int("MV_EU_supply", 0)
end,
technic_run = run,
})
minetest.register_node("technic:hydro_turbine_active", {
description = S("Hydro %s Generator"):format("MV"),
tiles = {"technic_hydro_turbine_top_active.png", "technic_machine_bottom.png",
"technic_hydro_turbine_side.png", "technic_hydro_turbine_side.png",
"technic_hydro_turbine_side.png", "technic_hydro_turbine_side.png"},
paramtype2 = "facedir",
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_mv=1, not_in_creative_inventory=1},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
drop = "technic:hydro_turbine",
technic_run = run,
technic_disabled_machine_name = "technic:hydro_turbine",
})
technic.register_machine("MV", "technic:hydro_turbine", technic.producer)
technic.register_machine("MV", "technic:hydro_turbine_active", technic.producer)

View File

@ -13,6 +13,7 @@ if technic.config:get_bool("enable_wind_mill") then
end
dofile(path.."/generator.lua")
dofile(path.."/solar_array.lua")
dofile(path.."/hydro_turbine.lua")
-- Machines
dofile(path.."/alloy_furnace.lua")
@ -20,6 +21,7 @@ dofile(path.."/electric_furnace.lua")
dofile(path.."/grinder.lua")
dofile(path.."/extractor.lua")
dofile(path.."/compressor.lua")
dofile(path.."/centrifuge.lua")
dofile(path.."/tool_workshop.lua")

View File

@ -12,6 +12,16 @@
local power_radius = 12
minetest.register_craft({
output = 'technic:power_radiator 1',
recipe = {
{'technic:stainless_steel_ingot', 'technic:mv_transformer', 'technic:stainless_steel_ingot'},
{'technic:copper_coil', 'technic:machine_casing', 'technic:copper_coil'},
{'technic:rubber', 'technic:mv_cable', 'technic:rubber'},
}
})
------------------------------------------------------------------
-- API for inductive powered nodes:
-- Use the functions below to set the corresponding callbacks
@ -135,21 +145,13 @@ minetest.register_node("technic:power_radiator", {
end
})
minetest.register_craft({
output = 'technic:power_radiator 1',
recipe = {
{'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot'},
{'technic:copper_coil', 'technic:mv_transformer', 'technic:copper_coil'},
{'technic:rubber', 'technic:mv_cable0', 'technic:rubber'},
}
})
minetest.register_abm({
label = "Machines: run power radiator",
nodenames = {"technic:power_radiator"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.env:get_meta(pos)
local meta = minetest.get_meta(pos)
local eu_input = meta:get_int("MV_EU_input")
local eu_demand = meta:get_int("MV_EU_demand")

View File

@ -4,7 +4,7 @@ minetest.register_craft({
recipe = {
{'technic:solar_array_lv', 'technic:solar_array_lv', 'technic:solar_array_lv'},
{'technic:carbon_steel_ingot', 'technic:mv_transformer', 'technic:carbon_steel_ingot'},
{'', 'technic:mv_cable0', ''},
{'', 'technic:mv_cable', ''},
}
})

View File

@ -5,26 +5,97 @@ minetest.register_alias("tool_workshop", "technic:tool_workshop")
local S = technic.getter
local tube_entry = "^pipeworks_tube_connection_wooden.png"
minetest.register_craft({
output = 'technic:tool_workshop',
recipe = {
{'group:wood', 'group:wood', 'group:wood'},
{'group:wood', 'default:diamond', 'group:wood'},
{'default:stone', 'default:copper_ingot', 'default:stone'},
{'group:wood', 'default:diamond', 'group:wood'},
{'mesecons_pistons:piston_sticky_off', 'technic:machine_casing', 'technic:carbon_cloth'},
{'default:obsidian', 'technic:mv_cable', 'default:obsidian'},
}
})
local workshop_demand = {5000, 3500, 2000}
local workshop_formspec =
"invsize[8,9;]"..
"size[8,9;]"..
"list[current_name;src;3,1;1,1;]"..
"label[0,0;"..S("%s Tool Workshop"):format("MV").."]"..
"list[current_player;main;0,5;8,4;]"
"list[current_name;upgrade1;1,3;1,1;]"..
"list[current_name;upgrade2;2,3;1,1;]"..
"label[1,4;"..S("Upgrade Slots").."]"..
"list[current_player;main;0,5;8,4;]"..
"listring[current_player;main]"..
"listring[current_name;src]"..
"listring[current_player;main]"..
"listring[current_name;upgrade1]"..
"listring[current_player;main]"..
"listring[current_name;upgrade2]"..
"listring[current_player;main]"
local run = function(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local eu_input = meta:get_int("MV_EU_input")
local machine_name = S("%s Tool Workshop"):format("MV")
local machine_node = "technic:tool_workshop"
-- Setup meta data if it does not exist.
if not eu_input then
meta:set_int("MV_EU_demand", workshop_demand[1])
meta:set_int("MV_EU_input", 0)
return
end
local EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
local repairable = false
local srcstack = inv:get_stack("src", 1)
if not srcstack:is_empty() then
local itemdef = minetest.registered_items[srcstack:get_name()]
if itemdef and
(not itemdef.wear_represents or
itemdef.wear_represents == "mechanical_wear") and
srcstack:get_wear() ~= 0 then
repairable = true
end
end
technic.handle_machine_pipeworks(pos, tube_upgrade, function (pos, x_velocity, z_velocity)
if not repairable then
technic.send_items(pos, x_velocity, z_velocity, "src")
end
end)
if not repairable then
meta:set_string("infotext", S("%s Idle"):format(machine_name))
meta:set_int("MV_EU_demand", 0)
return
end
if eu_input < workshop_demand[EU_upgrade+1] then
meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
elseif eu_input >= workshop_demand[EU_upgrade+1] then
meta:set_string("infotext", S("%s Active"):format(machine_name))
srcstack:add_wear(-1000)
inv:set_stack("src", 1, srcstack)
end
meta:set_int("MV_EU_demand", workshop_demand[EU_upgrade+1])
end
minetest.register_node("technic:tool_workshop", {
description = S("%s Tool Workshop"):format("MV"),
tiles = {"technic_workshop_top.png", "technic_machine_bottom.png", "technic_workshop_side.png",
"technic_workshop_side.png", "technic_workshop_side.png", "technic_workshop_side.png"},
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
paramtype2 = "facedir",
tiles = {
"technic_workshop_top.png"..tube_entry,
"technic_machine_bottom.png"..tube_entry,
"technic_workshop_side.png"..tube_entry,
"technic_workshop_side.png"..tube_entry,
"technic_workshop_side.png"..tube_entry,
"technic_workshop_side.png"
},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_mv=1, tubedevice=1, tubedevice_receiver=1},
connect_sides = {"bottom", "back", "left", "right"},
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
@ -32,61 +103,25 @@ minetest.register_node("technic:tool_workshop", {
meta:set_string("formspec", workshop_formspec)
local inv = meta:get_inventory()
inv:set_size("src", 1)
inv:set_size("upgrade1", 1)
inv:set_size("upgrade2", 1)
end,
can_dig = technic.machine_can_dig,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
tube = {
can_insert = function (pos, node, stack, direction)
return minetest.get_meta(pos):get_inventory():room_for_item("src", stack)
end,
insert_object = function (pos, node, stack, direction)
return minetest.get_meta(pos):get_inventory():add_item("src", stack)
end,
connect_sides = {left = 1, right = 1, back = 1, top = 1, bottom = 1},
},
technic_run = run,
after_place_node = pipeworks.after_place,
after_dig_node = technic.machine_after_dig_node
})
minetest.register_abm({
nodenames = {"technic:tool_workshop"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local eu_input = meta:get_int("MV_EU_input")
local machine_name = S("%s Tool Workshop"):format("MV")
local machine_node = "technic:tool_workshop"
local demand = 5000
-- Setup meta data if it does not exist.
if not eu_input then
meta:set_int("MV_EU_demand", demand)
meta:set_int("MV_EU_input", 0)
return
end
-- Power off automatically if no longer connected to a switching station
technic.switching_station_timeout_count(pos, "MV")
local repairable = false
local srcstack = inv:get_stack("src", 1)
if not srcstack:is_empty() then
local itemdef = minetest.registered_items[srcstack:get_name()]
if itemdef and
(not itemdef.wear_represents or
itemdef.wear_represents == "mechanical_wear") and
srcstack:get_wear() ~= 0 then
repairable = true
end
end
if not repairable then
meta:set_string("infotext", S("%s Idle"):format(machine_name))
meta:set_int("MV_EU_demand", 0)
return
end
if eu_input < demand then
meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
elseif eu_input >= demand then
meta:set_string("infotext", S("%s Active"):format(machine_name))
srcstack:add_wear(-1000)
inv:set_stack("src", 1, srcstack)
end
meta:set_int("MV_EU_demand", demand)
end
})
technic.register_machine("MV", "technic:tool_workshop", technic.receiver)

View File

@ -13,9 +13,9 @@ minetest.register_craft({
minetest.register_craft({
output = 'technic:wind_mill',
recipe = {
{'', 'technic:carbon_steel_ingot', ''},
{'technic:carbon_steel_ingot', 'technic:motor', 'technic:carbon_steel_ingot'},
{'', 'technic:carbon_steel_block', ''},
{'', 'technic:motor', ''},
{'technic:carbon_steel_ingot', 'technic:carbon_steel_block', 'technic:carbon_steel_ingot'},
{'', 'technic:mv_cable', ''},
}
})
@ -29,11 +29,49 @@ minetest.register_node("technic:wind_mill_frame", {
paramtype = "light",
})
local function check_wind_mill(pos)
if pos.y < 30 then
return false
end
pos = {x=pos.x, y=pos.y, z=pos.z}
for i = 1, 20 do
pos.y = pos.y - 1
local node = minetest.get_node_or_nil(pos)
if not node then
-- we reached CONTENT_IGNORE, we can assume, that nothing changed
-- as the user will have to load the block to change it
return
end
if node.name ~= "technic:wind_mill_frame" then
return false
end
end
return true
end
local run = function(pos, node)
local meta = minetest.get_meta(pos)
local machine_name = S("Wind %s Generator"):format("MV")
local check = check_wind_mill(pos)
if check == false then
meta:set_int("MV_EU_supply", 0)
meta:set_string("infotext", S("%s Improperly Placed"):format(machine_name))
elseif check == true then
local power = math.min(pos.y * 100, 5000)
meta:set_int("MV_EU_supply", power)
meta:set_string("infotext", S("@1 (@2)", machine_name,
technic.EU_string(power)))
end
-- check == nil: assume nothing has changed
end
minetest.register_node("technic:wind_mill", {
description = S("Wind %s Generator"):format("MV"),
tiles = {"technic_carbon_steel_block.png"},
paramtype2 = "facedir",
groups = {cracky=1},
groups = {cracky=1, technic_machine=1, technic_mv=1},
connect_sides = {"top", "bottom", "back", "left", "right"},
sounds = default.node_sound_stone_defaults(),
drawtype = "nodebox",
paramtype = "light",
@ -50,41 +88,8 @@ minetest.register_node("technic:wind_mill", {
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Wind %s Generator"):format("MV"))
meta:set_int("MV_EU_supply", 0)
end,
})
local function check_wind_mill(pos)
if pos.y < 30 then
return false
end
for i = 1, 20 do
local node = minetest.get_node({x=pos.x, y=pos.y-i, z=pos.z})
if node.name ~= "technic:wind_mill_frame" then
return false
end
end
return true
end
minetest.register_abm({
nodenames = {"technic:wind_mill"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local machine_name = S("Wind %s Generator"):format("MV")
local power = math.min(pos.y * 100, 5000)
if not check_wind_mill(pos) then
meta:set_int("MV_EU_supply", 0)
meta:set_string("infotext", S("%s Improperly Placed"):format(machine_name))
return
else
meta:set_int("MV_EU_supply", power)
end
meta:set_string("infotext", machine_name.." ("..power.."EU)")
end
end,
technic_run = run,
})
technic.register_machine("MV", "technic:wind_mill", technic.producer)

View File

@ -8,6 +8,7 @@ dofile(path.."/MV/init.lua")
dofile(path.."/HV/init.lua")
dofile(path.."/switching_station.lua")
dofile(path.."/power_monitor.lua")
dofile(path.."/supply_converter.lua")
dofile(path.."/other/init.lua")

View File

@ -0,0 +1,109 @@
local S = technic.getter
local desc = S("Administrative World Anchor")
local function compute_forceload_positions(pos, meta)
local radius = meta:get_int("radius")
local minpos = vector.subtract(pos, vector.new(radius, radius, radius))
local maxpos = vector.add(pos, vector.new(radius, radius, radius))
local minbpos = {}
local maxbpos = {}
for _, coord in ipairs({"x","y","z"}) do
minbpos[coord] = math.floor(minpos[coord] / 16) * 16
maxbpos[coord] = math.floor(maxpos[coord] / 16) * 16
end
local flposes = {}
for x = minbpos.x, maxbpos.x, 16 do
for y = minbpos.y, maxbpos.y, 16 do
for z = minbpos.z, maxbpos.z, 16 do
table.insert(flposes, vector.new(x, y, z))
end
end
end
return flposes
end
local function currently_forceloaded_positions(meta)
local ser = meta:get_string("forceloaded")
return ser == "" and {} or minetest.deserialize(ser)
end
local function forceload_off(meta)
local flposes = currently_forceloaded_positions(meta)
meta:set_string("forceloaded", "")
for _, p in ipairs(flposes) do
minetest.forceload_free_block(p)
end
end
local function forceload_on(pos, meta)
local want_flposes = compute_forceload_positions(pos, meta)
local have_flposes = {}
for _, p in ipairs(want_flposes) do
if minetest.forceload_block(p) then
table.insert(have_flposes, p)
end
end
meta:set_string("forceloaded", #have_flposes == 0 and "" or minetest.serialize(have_flposes))
end
local function set_display(pos, meta)
meta:set_string("infotext", S(meta:get_int("enabled") ~= 0 and "%s Enabled" or "%s Disabled"):format(desc))
meta:set_string("formspec",
"size[5,3.5]"..
"item_image[0,0;1,1;technic:admin_anchor]"..
"label[1,0;"..minetest.formspec_escape(desc).."]"..
"label[0,1;"..minetest.formspec_escape(S("Owner:").." "..meta:get_string("owner")).."]"..
(meta:get_int("locked") == 0 and
"button[3,1;2,1;lock;"..minetest.formspec_escape(S("Unlocked")).."]" or
"button[3,1;2,1;unlock;"..minetest.formspec_escape(S("Locked")).."]")..
"field[0.25,2.3;1,1;radius;"..minetest.formspec_escape(S("Radius:"))..";"..meta:get_int("radius").."]"..
(meta:get_int("enabled") == 0 and
"button[3,2;2,1;enable;"..minetest.formspec_escape(S("Disabled")).."]" or
"button[3,2;2,1;disable;"..minetest.formspec_escape(S("Enabled")).."]")..
"label[0,3;"..minetest.formspec_escape(S("Keeping %d/%d map blocks loaded"):format(#currently_forceloaded_positions(meta), #compute_forceload_positions(pos, meta))).."]")
end
minetest.register_node("technic:admin_anchor", {
description = desc,
drawtype = "normal",
tiles = {"technic_admin_anchor.png"},
is_ground_content = true,
groups = {cracky=3, not_in_creative_inventory=1},
sounds = default.node_sound_stone_defaults(),
after_place_node = function (pos, placer)
local meta = minetest.get_meta(pos)
if placer and placer:is_player() then
meta:set_string("owner", placer:get_player_name())
end
set_display(pos, meta)
end,
can_dig = function (pos, player)
local meta = minetest.get_meta(pos)
return meta:get_int("locked") == 0 or (player and player:is_player() and player:get_player_name() == meta:get_string("owner"))
end,
on_destruct = function (pos)
local meta = minetest.get_meta(pos)
forceload_off(meta)
end,
on_receive_fields = function (pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
if (meta:get_int("locked") ~= 0 or fields.lock) and
not (sender and sender:is_player() and
sender:get_player_name() == meta:get_string("owner")) then
return
end
if fields.unlock then meta:set_int("locked", 0) end
if fields.lock then meta:set_int("locked", 1) end
if fields.disable or fields.enable or fields.radius then
forceload_off(meta)
if fields.disable then meta:set_int("enabled", 0) end
if fields.enable then meta:set_int("enabled", 1) end
if fields.radius and string.find(fields.radius, "^[0-9]+$") and tonumber(fields.radius) < 256 then meta:set_int("radius", fields.radius) end
if meta:get_int("enabled") ~= 0 then
forceload_on(pos, meta)
end
end
set_display(pos, meta)
end,
})

View File

@ -12,8 +12,24 @@ minetest.register_craft({
}
})
local machine_name = S("Fuel-Fired Alloy Furnace")
local formspec =
"size[8,9]"..
"label[0,0;"..machine_name.."]"..
"image[2,2;1,1;default_furnace_fire_bg.png]"..
"list[current_name;fuel;2,3;1,1;]"..
"list[current_name;src;2,1;2,1;]"..
"list[current_name;dst;5,1;2,2;]"..
"list[current_player;main;0,5;8,4;]"..
"listring[current_name;dst]"..
"listring[current_player;main]"..
"listring[current_name;src]"..
"listring[current_player;main]"..
"listring[current_name;fuel]"..
"listring[current_player;main]"
minetest.register_node("technic:coal_alloy_furnace", {
description = S("Fuel-Fired Alloy Furnace"),
description = machine_name,
tiles = {"technic_coal_alloy_furnace_top.png", "technic_coal_alloy_furnace_bottom.png",
"technic_coal_alloy_furnace_side.png", "technic_coal_alloy_furnace_side.png",
"technic_coal_alloy_furnace_side.png", "technic_coal_alloy_furnace_front.png"},
@ -22,9 +38,9 @@ minetest.register_node("technic:coal_alloy_furnace", {
legacy_facedir_simple = true,
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec", coal_alloy_furnace_formspec)
meta:set_string("infotext", S("Fuel-Fired Alloy Furnace"))
local meta = minetest.get_meta(pos)
meta:set_string("formspec", formspec)
meta:set_string("infotext", machine_name)
local inv = meta:get_inventory()
inv:set_size("fuel", 1)
inv:set_size("src", 2)
@ -37,7 +53,7 @@ minetest.register_node("technic:coal_alloy_furnace", {
})
minetest.register_node("technic:coal_alloy_furnace_active", {
description = S("Fuel-Fired Alloy Furnace"),
description = machine_name,
tiles = {"technic_coal_alloy_furnace_top.png", "technic_coal_alloy_furnace_bottom.png",
"technic_coal_alloy_furnace_side.png", "technic_coal_alloy_furnace_side.png",
"technic_coal_alloy_furnace_side.png", "technic_coal_alloy_furnace_front_active.png"},
@ -54,6 +70,7 @@ minetest.register_node("technic:coal_alloy_furnace_active", {
})
minetest.register_abm({
label = "Machines: run coal alloy furnace",
nodenames = {"technic:coal_alloy_furnace", "technic:coal_alloy_furnace_active"},
interval = 1,
chance = 1,
@ -68,15 +85,6 @@ minetest.register_abm({
end
local recipe = nil
local machine_name = S("Fuel-Fired Alloy Furnace")
local formspec =
"size[8,9]"..
"label[0,0;"..machine_name.."]"..
"image[2,2;1,1;default_furnace_fire_bg.png]"..
"list[current_name;fuel;2,3;1,1;]"..
"list[current_name;src;2,1;2,1;]"..
"list[current_name;dst;5,1;2,2;]"..
"list[current_player;main;0,5;8,4;]"
for i, name in pairs({
"fuel_totaltime",
@ -124,7 +132,13 @@ minetest.register_abm({
"list[current_name;fuel;2,3;1,1;]"..
"list[current_name;src;2,1;2,1;]"..
"list[current_name;dst;5,1;2,2;]"..
"list[current_player;main;0,5;8,4;]")
"list[current_player;main;0,5;8,4;]"..
"listring[current_name;dst]"..
"listring[current_player;main]"..
"listring[current_name;src]"..
"listring[current_player;main]"..
"listring[current_name;fuel]"..
"listring[current_player;main]")
return
end
@ -141,10 +155,11 @@ minetest.register_abm({
-- Next take a hard look at the fuel situation
local fuel = nil
local afterfuel
local fuellist = inv:get_list("fuel")
if fuellist then
fuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
end
if fuel.time <= 0 then
@ -157,9 +172,7 @@ minetest.register_abm({
meta:set_string("fuel_totaltime", fuel.time)
meta:set_string("fuel_time", 0)
local stack = inv:get_stack("fuel", 1)
stack:take_item()
inv:set_stack("fuel", 1, stack)
inv:set_stack("fuel", 1, afterfuel.items[1])
end,
})

View File

@ -1,75 +1,68 @@
local S = technic.getter
local function deploy_node(inv, slot_name, pos1, node1, node)
if node1.name == "air" then
if not inv:is_empty(slot_name) then
stack1=inv:get_list(slot_name)
local def = stack1[1]:get_definition()
if def.type == "node" then
node_to_be_placed={name=stack1[1]:get_name(), param1=0, param2=node.param2}
minetest.set_node(pos1,node_to_be_placed)
stack1[1]:take_item()
inv:set_stack(slot_name, 1, stack1[1])
elseif def.type == "craft" then
if def.on_place then
-- print("deploy_node: item has on_place. trying...")
local ok, stk = pcall(def.on_place, stack1[1], nil, {
-- Fake pointed_thing
type = "node",
above = pos1,
under = { x=pos1.x, y=pos1.y-1, z=pos1.z },
})
if ok then
-- print("deploy_node: on_place succeeded!")
inv:set_stack(slot_name, 1, stk or stack1[1])
return
-- else
-- print("deploy_node: WARNING: error while running on_place: "..tostring(stk))
end
end
minetest.item_place_object(stack1[1], nil, {
local function deploy_node(inv, slot_name, pos, node, machine_node)
if node.param2 > 3 then return end
if node.name ~= "air" then
if node.name == "ignore" or
node.name == "default:lava_source" or
node.name == "default:lava_flowing" or
node.name == "default:water_source" or
node.name == "default:water_flowing" then
return
end
local drops = minetest.get_node_drops(node.name, "")
local remove_to = false
for i, item in ipairs(drops) do
if not inv:room_for_item(slot_name, item) then
remove_to = i - 1
break
end
inv:add_item(slot_name, item)
end
if remove_to then
for i = 1, remove_to do
inv:remove_item(slot_name, drops[i])
end
else
minetest.remove_node(pos)
end
return
end
if not inv:is_empty(slot_name) then
local stack = inv:get_list(slot_name)[1]
local def = stack:get_definition()
if def.type == "node" then
minetest.set_node(pos, {
name = stack:get_name(),
param2 = machine_node.param2
})
stack:take_item()
inv:set_stack(slot_name, 1, stack)
elseif def.type == "craft" then
if def.on_place then
-- Use pcall to avoid nil placer errors.
-- TODO: Do without pcall.
local ok, stk = pcall(def.on_place, stack, nil, {
-- Fake pointed_thing
type = "node",
above = pos1,
under = pos1,
above = pos,
under = {x=pos.x, y=pos.y-1, z=pos.z},
})
inv:set_stack(slot_name, 1, nil)
end
end
return
end
if node1.name == "ignore" or
node1.name == "default:lava_source" or
node1.name == "default:lava_flowing" or
node1.name == "default:water_source" or
node1.name == "default:water_flowing"
then return end
if inv:room_for_item(slot_name,node1) then
local def = minetest.registered_nodes[node1.name]
if not def then return end
local drop = def.drop or node1.name
if type(drop) == "table" then
local pr = PseudoRandom(math.random())
local c = 0
local loop = 0 -- Prevent infinite loop
while (c < (drop.max_items or 1)) and (loop < 1000) do
local i = math.floor(pr:next(1, #drop.items))
if pr:next(1, drop.items[i].rarity or 1) == 1 then
for _,item in ipairs(drop.items[i].items) do
inv:add_item(slot_name,item)
end
c = c + 1
if ok then
inv:set_stack(slot_name, 1, stk or stack)
return
end
loop = loop + 1
end
minetest.remove_node(pos1)
elseif type(drop) == "string" then
inv:add_item(slot_name,drop)
minetest.remove_node(pos1)
minetest.item_place_object(stack, nil, {
-- Fake pointed_thing
type = "node",
above = pos,
under = pos,
})
inv:set_stack(slot_name, 1, nil)
end
end
end
minetest.register_craft({
@ -92,273 +85,108 @@ minetest.register_craft({
})
local function mk1_on(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local pos1={}
pos1.x=pos.x
pos1.y=pos.y
pos1.z=pos.z
if node.param2==3 then pos1.x=pos1.x+1 end
if node.param2==2 then pos1.z=pos1.z+1 end
if node.param2==1 then pos1.x=pos1.x-1 end
if node.param2==0 then pos1.z=pos1.z-1 end
if node.name == "technic:constructor_mk1_off" then
technic.swap_node(pos,"technic:constructor_mk1_on")
nodeupdate(pos)
local node1=minetest.get_node(pos1)
deploy_node (inv,"slot1",pos1,node1,node)
end
end
local function mk1_off(pos, node)
if node.name == "technic:constructor_mk1_on" then
technic.swap_node(pos,"technic:constructor_mk1_off")
nodeupdate(pos)
end
end
minetest.register_node("technic:constructor_mk1_off", {
description = S("Constructor Mk%d"):format(1),
tile_images = {"technic_constructor_mk1_top_off.png","technic_constructor_mk1_bottom_off.png","technic_constructor_mk1_side2_off.png","technic_constructor_mk1_side1_off.png",
"technic_constructor_back.png","technic_constructor_front_off.png"},
is_ground_content = true,
paramtype2 = "facedir",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon_receptor_off = 1, mesecon_effector_off = 1, mesecon = 2},
mesecons= {effector={action_on=mk1_on}},
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec",
"invsize[8,9;]"..
"label[0,0;"..S("Constructor Mk%d"):format(1).."]"..
"label[5,0;"..S("Slot %d"):format(1).."]"..
"list[current_name;slot1;6,0;1,1;]"..
"list[current_player;main;0,5;8,4;]")
meta:set_string("infotext", S("Constructor Mk%d"):format(1))
local inv = meta:get_inventory()
inv:set_size("slot1", 1)
end,
can_dig = function(pos,player)
local function make_on(mark, length)
return function(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("slot1")
end,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
})
local dir = vector.new()
if node.param2 == 3 then dir.x = 1 end
if node.param2 == 2 then dir.z = 1 end
if node.param2 == 1 then dir.x = -1 end
if node.param2 == 0 then dir.z = -1 end
minetest.register_node("technic:constructor_mk1_on", {
description = S("Constructor Mk%d"):format(1),
tile_images = {"technic_constructor_mk1_top_on.png","technic_constructor_mk1_bottom_on.png","technic_constructor_mk1_side2_on.png","technic_constructor_mk1_side1_on.png",
"technic_constructor_back.png","technic_constructor_front_on.png"},
paramtype2 = "facedir",
drop = "technic:constructor_mk1_off",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,mesecon = 2,not_in_creative_inventory=1},
mesecons= {effector={action_off=mk1_off}},
sounds = default.node_sound_stone_defaults(),
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
})
local place_pos = vector.new(pos)
--Constructor Mk2
local function mk2_on(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local pos1={}
local pos2={}
pos1.x=pos.x
pos1.y=pos.y
pos1.z=pos.z
pos2.x=pos.x
pos2.y=pos.y
pos2.z=pos.z
if node.param2==3 then pos1.x=pos1.x+1 pos2.x=pos2.x+2 end
if node.param2==2 then pos1.z=pos1.z+1 pos2.z=pos2.z+2 end
if node.param2==1 then pos1.x=pos1.x-1 pos2.x=pos2.x-2 end
if node.param2==0 then pos1.z=pos1.z-1 pos2.z=pos2.z-2 end
if node.name == "technic:constructor_mk2_off" then
technic.swap_node(pos,"technic:constructor_mk2_on")
nodeupdate(pos)
local node1=minetest.get_node(pos1)
deploy_node (inv,"slot1",pos1,node1,node)
local node1=minetest.get_node(pos2)
deploy_node (inv,"slot2",pos2,node1,node)
if node.name == "technic:constructor_mk"..mark.."_off" then
technic.swap_node(pos, "technic:constructor_mk"..mark.."_on")
minetest.check_for_falling(pos)
for i = 1, length do
place_pos = vector.add(place_pos, dir)
local place_node = minetest.get_node(place_pos)
deploy_node(inv, "slot"..i, place_pos, place_node, node)
end
end
end
end
local function mk2_off(pos, node)
if node.name == "technic:constructor_mk2_on" then
technic.swap_node(pos,"technic:constructor_mk2_off")
nodeupdate(pos)
local function make_off(mark)
return function(pos, node)
if node.name == "technic:constructor_mk"..mark.."_on" then
technic.swap_node(pos,"technic:constructor_mk"..mark.."_off")
minetest.check_for_falling(pos)
end
end
end
minetest.register_node("technic:constructor_mk2_off", {
description = S("Constructor Mk%d"):format(2),
tile_images = {"technic_constructor_mk2_top_off.png","technic_constructor_mk2_bottom_off.png","technic_constructor_mk2_side2_off.png","technic_constructor_mk2_side1_off.png",
"technic_constructor_back.png","technic_constructor_front_off.png"},
is_ground_content = true,
paramtype2 = "facedir",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2},
mesecons= {effector={action_on=mk2_on}},
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec",
"invsize[8,9;]"..
"label[0,0;"..S("Constructor Mk%d"):format(2).."]"..
"label[5,0;"..S("Slot %d"):format(1).."]"..
"list[current_name;slot1;6,0;1,1;]"..
"label[5,1;"..S("Slot %d"):format(2).."]"..
"list[current_name;slot2;6,1;1,1;]"..
"list[current_player;main;0,5;8,4;]")
meta:set_string("infotext", S("Constructor Mk%d"):format(2))
local inv = meta:get_inventory()
inv:set_size("slot1", 1)
inv:set_size("slot2", 1)
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:is_empty("slot1")==false or inv:is_empty("slot2")==false then return false end
return true
end,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
})
minetest.register_node("technic:constructor_mk2_on", {
description = S("Constructor Mk%d"):format(2),
tile_images = {"technic_constructor_mk2_top_on.png","technic_constructor_mk2_bottom_on.png","technic_constructor_mk2_side2_on.png","technic_constructor_mk2_side1_on.png",
"technic_constructor_back.png","technic_constructor_front_on.png"},
is_ground_content = true,
paramtype2 = "facedir",
drop = "technic:constructor_mk2_off",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2, not_in_creative_inventory=1},
mesecons = {effector={action_off=mk2_off}},
sounds = default.node_sound_stone_defaults(),
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
})
local function make_constructor(mark, length)
minetest.register_node("technic:constructor_mk"..mark.."_off", {
description = S("Constructor Mk%d"):format(mark),
tiles = {"technic_constructor_mk"..mark.."_top_off.png",
"technic_constructor_mk"..mark.."_bottom_off.png",
"technic_constructor_mk"..mark.."_side2_off.png",
"technic_constructor_mk"..mark.."_side1_off.png",
"technic_constructor_back.png",
"technic_constructor_front_off.png"},
paramtype2 = "facedir",
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, mesecon = 2},
mesecons = {effector = {action_on = make_on(mark, length)}},
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local formspec = "size[8,9;]"..
"label[0,0;"..S("Constructor Mk%d"):format(mark).."]"..
"list[current_player;main;0,5;8,4;]"
for i = 1, length do
formspec = formspec
.."label[5,"..(i - 1)..";"..S("Slot %d"):format(i).."]"
.."list[current_name;slot"..i
..";6,"..(i - 1)..";1,1;]"
end
meta:set_string("formspec", formspec)
meta:set_string("infotext", S("Constructor Mk%d"):format(mark))
local inv = meta:get_inventory()
for i = 1, length do
inv:set_size("slot"..i, 1)
end
end,
can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
for i = 1, length do
if not inv:is_empty("slot"..i) then
return false
end
end
return true
end,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
on_rotate = screwdriver.rotate_simple
})
-- Constructor Mk3
local function mk3_on(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local pos1={}
local pos2={}
local pos3={}
local pos4={}
pos1.x=pos.x
pos1.y=pos.y
pos1.z=pos.z
pos2.x=pos.x
pos2.y=pos.y
pos2.z=pos.z
pos3.x=pos.x
pos3.y=pos.y
pos3.z=pos.z
pos4.x=pos.x
pos4.y=pos.y
pos4.z=pos.z
if node.param2==3 then pos1.x=pos1.x+1 pos2.x=pos2.x+2 pos3.x=pos3.x+3 pos4.x=pos4.x+4 end
if node.param2==2 then pos1.z=pos1.z+1 pos2.z=pos2.z+2 pos3.z=pos3.z+3 pos4.z=pos4.z+4 end
if node.param2==1 then pos1.x=pos1.x-1 pos2.x=pos2.x-2 pos3.x=pos3.x-3 pos4.x=pos4.x-4 end
if node.param2==0 then pos1.z=pos1.z-1 pos2.z=pos2.z-2 pos3.z=pos3.z-3 pos4.z=pos4.z-4 end
if node.name == "technic:constructor_mk3_off" then
technic.swap_node(pos,"technic:constructor_mk3_on")
nodeupdate(pos)
local node1=minetest.get_node(pos1)
deploy_node (inv,"slot1",pos1,node1,node)
local node1=minetest.get_node(pos2)
deploy_node (inv,"slot2",pos2,node1,node)
local node1=minetest.get_node(pos3)
deploy_node (inv,"slot3",pos3,node1,node)
local node1=minetest.get_node(pos4)
deploy_node (inv,"slot4",pos4,node1,node)
end
minetest.register_node("technic:constructor_mk"..mark.."_on", {
tiles = {"technic_constructor_mk"..mark.."_top_on.png",
"technic_constructor_mk"..mark.."_bottom_on.png",
"technic_constructor_mk"..mark.."_side2_on.png",
"technic_constructor_mk"..mark.."_side1_on.png",
"technic_constructor_back.png",
"technic_constructor_front_on.png"},
paramtype2 = "facedir",
drop = "technic:constructor_mk"..mark.."_off",
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
mesecon=2, not_in_creative_inventory=1},
mesecons= {effector = {action_off = make_off(mark)}},
sounds = default.node_sound_stone_defaults(),
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
on_rotate = false
})
end
local function mk3_off(pos, node)
if node.name == "technic:constructor_mk3_on" then
technic.swap_node(pos,"technic:constructor_mk3_off")
nodeupdate(pos)
end
end
minetest.register_node("technic:constructor_mk3_off", {
description = S("Constructor Mk%d"):format(3),
tile_images = {"technic_constructor_mk3_top_off.png","technic_constructor_mk3_bottom_off.png","technic_constructor_mk3_side2_off.png","technic_constructor_mk3_side1_off.png",
"technic_constructor_back.png","technic_constructor_front_off.png"},
paramtype2 = "facedir",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2},
mesecons = {effector={action_on=mk3_on}},
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec",
"invsize[8,9;]"..
"label[0,0;"..S("Constructor Mk%d"):format(3).."]"..
"label[5,0;"..S("Slot %d"):format(1).."]"..
"list[current_name;slot1;6,0;1,1;]"..
"label[5,1;"..S("Slot %d"):format(2).."]"..
"list[current_name;slot2;6,1;1,1;]"..
"label[5,2;"..S("Slot %d"):format(3).."]"..
"list[current_name;slot3;6,2;1,1;]"..
"label[5,3;"..S("Slot %d"):format(4).."]"..
"list[current_name;slot4;6,3;1,1;]"..
"list[current_player;main;0,5;8,4;]")
meta:set_string("infotext", S("Constructor Mk%d"):format(3))
local inv = meta:get_inventory()
inv:set_size("slot1", 1)
inv:set_size("slot2", 1)
inv:set_size("slot3", 1)
inv:set_size("slot4", 1)
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:is_empty("slot1")==false or inv:is_empty("slot2")==false or inv:is_empty("slot3")==false or inv:is_empty("slot4")==false then return false end
return true
end,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
})
minetest.register_node("technic:constructor_mk3_on", {
description = S("Constructor Mk%d"):format(3),
tile_images = {"technic_constructor_mk3_top_on.png","technic_constructor_mk3_bottom_on.png","technic_constructor_mk3_side2_on.png","technic_constructor_mk3_side1_on.png",
"technic_constructor_back.png","technic_constructor_front_on.png"},
is_ground_content = true,
paramtype2 = "facedir",
drop = "technic:constructor_mk3_off",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2,not_in_creative_inventory=1},
mesecons = {effector={action_off=mk3_off}},
sounds = default.node_sound_stone_defaults(),
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
})
make_constructor(1, 1)
make_constructor(2, 2)
make_constructor(3, 4)

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,13 @@ local path = technic.modpath.."/machines/other"
-- mesecons and tubes related
dofile(path.."/injector.lua")
dofile(path.."/constructor.lua")
if minetest.get_modpath("mesecons_mvps") ~= nil then
if technic.config:get_bool("enable_frames") and minetest.get_modpath("mesecons_mvps") ~= nil then
dofile(path.."/frames.lua")
end
-- Coal-powered machines
dofile(path.."/coal_alloy_furnace.lua")
dofile(path.."/coal_furnace.lua")
dofile(path.."/anchor.lua")

View File

@ -1,8 +1,12 @@
local S = technic.getter
local fs_helpers = pipeworks.fs_helpers
local tube_entry = "^pipeworks_tube_connection_metallic.png"
local function inject_items (pos)
local meta=minetest.env:get_meta(pos)
local meta=minetest.get_meta(pos)
local inv = meta:get_inventory()
local mode=meta:get_string("mode")
if mode=="single items" then
@ -12,12 +16,9 @@ local function inject_items (pos)
if stack then
local item0=stack:to_table()
if item0 then
item0["count"]="1"
local item1=pipeworks.tube_item({x=pos.x,y=pos.y,z=pos.z},item0)
item1:get_luaentity().start_pos = {x=pos.x,y=pos.y,z=pos.z}
item1:setvelocity({x=0, y=-1, z=0})
item1:setacceleration({x=0, y=0, z=0})
stack:take_item(1);
item0["count"] = "1"
technic.tube_inject_item(pos, pos, vector.new(0, -1, 0), item0)
stack:take_item(1)
inv:set_stack("main", i, stack)
return
end
@ -31,10 +32,7 @@ local function inject_items (pos)
if stack then
local item0=stack:to_table()
if item0 then
local item1=pipeworks.tube_item({x=pos.x,y=pos.y,z=pos.z},item0)
item1:get_luaentity().start_pos = {x=pos.x,y=pos.y,z=pos.z}
item1:setvelocity({x=0, y=-1, z=0})
item1:setacceleration({x=0, y=0, z=0})
technic.tube_inject_item(pos, pos, vector.new(0, -1, 0), item0)
stack:clear()
inv:set_stack("main", i, stack)
return
@ -54,67 +52,100 @@ minetest.register_craft({
}
})
local function set_injector_formspec(meta)
local is_stack = meta:get_string("mode") == "whole stacks"
meta:set_string("formspec",
"size[8,9;]"..
"item_image[0,0;1,1;technic:injector]"..
"label[1,0;"..S("Self-Contained Injector").."]"..
(is_stack and
"button[0,1;2,1;mode_item;"..S("Stackwise").."]" or
"button[0,1;2,1;mode_stack;"..S("Itemwise").."]")..
"list[current_name;main;0,2;8,2;]"..
"list[current_player;main;0,5;8,4;]"..
"listring[]"..
fs_helpers.cycling_button(
meta,
pipeworks.button_base,
"splitstacks",
{
pipeworks.button_off,
pipeworks.button_on
}
)..pipeworks.button_label
)
end
minetest.register_node("technic:injector", {
description = S("Injector"),
tiles = {"technic_injector_top.png", "technic_injector_bottom.png", "technic_injector_side.png",
"technic_injector_side.png", "technic_injector_side.png", "technic_injector_side.png"},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice=1},
tube = {connect_sides={bottom=1}},
description = S("Self-Contained Injector"),
tiles = {
"technic_injector_top.png"..tube_entry,
"technic_injector_bottom.png",
"technic_injector_side.png"..tube_entry,
"technic_injector_side.png"..tube_entry,
"technic_injector_side.png"..tube_entry,
"technic_injector_side.png"
},
paramtype2 = "facedir",
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice=1, tubedevice_receiver=1},
tube = {
can_insert = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if meta:get_int("splitstacks") == 1 then
stack = stack:peek_item(1)
end
return meta:get_inventory():room_for_item("main", stack)
end,
insert_object = function(pos, node, stack, direction)
return minetest.get_meta(pos):get_inventory():add_item("main", stack)
end,
connect_sides = {left=1, right=1, back=1, top=1, bottom=1},
},
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec",
"invsize[8,9;]"..
"label[0,0;"..S("Injector").."]"..
"button[0,1;.8,.8;mode;]"..
"label[.8,1;"..S("Mode: %s"):format("single items").."]"..
"list[current_name;main;0,2;8,2;]"..
"list[current_player;main;0,5;8,4;]")
meta:set_string("infotext", S("Injector"))
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Self-Contained Injector"))
local inv = meta:get_inventory()
inv:set_size("main", 8*4)
inv:set_size("main", 8*2)
meta:set_string("mode","single items")
set_injector_formspec(meta)
end,
can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos);
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("main")
end,
on_receive_fields = function(pos, formanme, fields, sender)
local meta = minetest.env:get_meta(pos)
local mode=meta:get_string("mode")
if fields.mode then
if mode == "single items" then
mode = "whole stacks"
else
mode = "single items"
end
meta:set_string("mode", mode)
local meta = minetest.get_meta(pos)
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["fs_helpers_cycling:0:splitstacks"]
or fields["fs_helpers_cycling:1:splitstacks"] then
if not pipeworks.may_configure(pos, sender) then return end
fs_helpers.on_receive_fields(pos, fields)
end
meta:set_string("formspec",
"invsize[8,9;]"..
"label[0,0;"..S("Injector").."]"..
"button[0,1;.8,.8;mode;]"..
"label[.8,1;"..S("Mode: %s"):format(S(mode)).."]"..
"list[current_name;main;0,2;8,2;]"..
"list[current_player;main;0,5;8,4;]")
set_injector_formspec(meta)
end,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
after_place_node = pipeworks.after_place,
after_dig_node = pipeworks.after_dig
})
minetest.register_abm({
label = "Machines: run injector",
nodenames = {"technic:injector"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local pos1={}
pos1.x = pos.x
pos1.y = pos.y-1
pos1.z = pos.z
local meta=minetest.env:get_meta(pos1)
if meta:get_int("tubelike")==1 then inject_items (pos) end
local pos1 = vector.add(pos, vector.new(0, -1, 0))
local node1 = minetest.get_node(pos1)
if minetest.get_item_group(node1.name, "tubedevice") > 0 then
inject_items(pos)
end
end,
})

View File

@ -1,17 +0,0 @@
minetest.register_node("technic:tetris_machine_node1", {
tiles = {"tetris_machine_top.png", "technic_mv_battery_box_bottom.png", "tetris_machine_front1.png",
"tetris_machine_side1B.png", "tetris_machine_side1P.png", "tetris_machine_side1L.png"},
tile_images = {"technic_tetris_machine.png",},
is_ground_content = true,
groups = {cracky=1},
sounds = default.node_sound_stone_defaults(),
})
minetest.register_node("technic:tetris_machine_node2", {
tiles = {"tetris_machine_top.png", "technic_mv_battery_box_bottom.png", "tetris_machine_front2.png",
"tetris_machine_side2B.png", "tetris_machine_side2P.png", "tetris_machine_side2L.png"},
tile_images = {"technic_tetris_machine.png",},
is_ground_content = true,
groups = {cracky=1},
sounds = default.node_sound_stone_defaults(),
})

View File

@ -0,0 +1,69 @@
-- POWER MONITOR
-- The power monitor can be used to monitor how much power is available on a network,
-- similarly to the old "slave" switching stations.
local S = technic.getter
local cable_entry = "^technic_cable_connection_overlay.png"
minetest.register_craft({
output = "technic:power_monitor",
recipe = {
{"", "", ""},
{"", "technic:machine_casing", "default:copper_ingot"},
{"technic:lv_cable", "technic:lv_cable", "technic:lv_cable"}
}
})
minetest.register_node("technic:power_monitor",{
description = S("Power Monitor"),
tiles = {
"technic_power_monitor_sides.png",
"technic_power_monitor_sides.png"..cable_entry,
"technic_power_monitor_sides.png",
"technic_power_monitor_sides.png",
"technic_power_monitor_sides.png"..cable_entry,
"technic_power_monitor_front.png"
},
paramtype2 = "facedir",
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_all_tiers=1, technic_machine=1},
connect_sides = {"bottom", "back"},
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Power Monitor"))
end,
})
minetest.register_abm({
nodenames = {"technic:power_monitor"},
label = "Machines: run power monitor",
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local network_hash = technic.cables[minetest.hash_node_position(pos)]
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
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 supply = sw_meta:get_int("supply")
local demand = sw_meta:get_int("demand")
meta:set_string("infotext",
S("Power Monitor. Supply: @1 Demand: @2",
technic.EU_string(supply), technic.EU_string(demand)))
else
meta:set_string("infotext",S("Power Monitor Has No Network"))
end
end,
})
for tier in pairs(technic.machines) do
-- RE in order to use the "timeout" functions, although it consumes 0 power
technic.register_machine(tier, "technic:power_monitor", "RE")
end

View File

@ -1,7 +1,10 @@
local S = technic.getter
technic.register_recipe_type("alloy", S("Alloy cooking"), 2)
technic.register_recipe_type("alloy", {
description = S("Alloying"),
input_size = 2,
})
function technic.register_alloy_recipe(data)
data.time = data.time or 6
@ -10,19 +13,23 @@ end
local recipes = {
{"technic:copper_dust 3", "technic:tin_dust", "technic:bronze_dust 4"},
{"default:copper_ingot 3", "moreores:tin_ingot", "default:bronze_ingot 4"},
{"technic:wrought_iron_dust", "technic:coal_dust", "technic:carbon_steel_dust"},
{"technic:wrought_iron_ingot", "technic:coal_dust", "technic:carbon_steel_ingot"},
{"technic:carbon_steel_dust", "technic:coal_dust", "technic:cast_iron_dust"},
{"technic:carbon_steel_ingot", "technic:coal_dust", "technic:cast_iron_ingot"},
{"default:copper_ingot 3", "default:tin_ingot", "default:bronze_ingot 4"},
{"technic:wrought_iron_dust", "technic:coal_dust", "technic:carbon_steel_dust", 3},
{"technic:wrought_iron_ingot", "technic:coal_dust", "technic:carbon_steel_ingot", 3},
{"technic:carbon_steel_dust", "technic:coal_dust", "technic:cast_iron_dust", 3},
{"technic:carbon_steel_ingot", "technic:coal_dust", "technic:cast_iron_ingot", 3},
{"technic:carbon_steel_dust 3", "technic:chromium_dust", "technic:stainless_steel_dust 4"},
{"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_ingot 2", "technic:zinc_ingot", "technic:brass_ingot 3"},
{"default:copper_ingot 2", "technic:zinc_ingot", "technic:brass_ingot 3"},
{"default:sand 2", "technic:coal_dust 2", "technic:silicon_wafer"},
{"technic:silicon_wafer", "technic:gold_dust", "technic:doped_silicon_wafer"},
-- from https://en.wikipedia.org/wiki/Carbon_black
-- The highest volume use of carbon black is as a reinforcing filler in rubber products, especially tires.
-- "[Compounding a] pure gum vulcanizate … with 50% of its weight of carbon black improves its tensile strength and wear resistance …"
{"technic:raw_latex 4", "technic:coal_dust 2", "technic:rubber 6", 2},
}
for _, data in pairs(recipes) do
technic.register_alloy_recipe({input = {data[1], data[2]}, output = data[3]})
technic.register_alloy_recipe({input = {data[1], data[2]}, output = data[3], time = data[4]})
end

View File

@ -1,17 +1,70 @@
local digilines_path = minetest.get_modpath("digilines")
local S = technic.getter
local tube_entry = "^pipeworks_tube_connection_metallic.png"
local cable_entry = "^technic_cable_connection_overlay.png"
local fs_helpers = pipeworks.fs_helpers
technic.register_power_tool("technic:battery", 10000)
technic.register_power_tool("technic:red_energy_crystal", 50000)
technic.register_power_tool("technic:green_energy_crystal", 150000)
technic.register_power_tool("technic:blue_energy_crystal", 450000)
-- Battery recipes:
-- Tin-copper recipe:
minetest.register_craft({
output = 'technic:battery',
output = "technic:battery",
recipe = {
{'group:wood', 'default:copper_ingot', 'group:wood'},
{'group:wood', 'moreores:tin_ingot', 'group:wood'},
{'group:wood', 'default:copper_ingot', 'group:wood'},
{"group:wood", "default:copper_ingot", "group:wood"},
{"group:wood", "default:tin_ingot", "group:wood"},
{"group:wood", "default:copper_ingot", "group:wood"},
}
})
-- Sulfur-lead-water recipes:
-- With sulfur lumps:
-- With water:
minetest.register_craft({
output = "technic:battery",
recipe = {
{"group:wood", "technic:sulfur_lump", "group:wood"},
{"technic:lead_ingot", "bucket:bucket_water", "technic:lead_ingot"},
{"group:wood", "technic:sulfur_lump", "group:wood"},
},
replacements = {
{"bucket:bucket_water", "bucket:bucket_empty"}
}
})
-- With oil extract:
minetest.register_craft({
output = "technic:battery",
recipe = {
{"group:wood", "technic:sulfur_lump", "group:wood"},
{"technic:lead_ingot", "homedecor:oil_extract", "technic:lead_ingot"},
{"group:wood", "technic:sulfur_lump", "group:wood"},
}
})
-- With sulfur dust:
-- With water:
minetest.register_craft({
output = "technic:battery",
recipe = {
{"group:wood", "technic:sulfur_dust", "group:wood"},
{"technic:lead_ingot", "bucket:bucket_water", "technic:lead_ingot"},
{"group:wood", "technic:sulfur_dust", "group:wood"},
},
replacements = {
{"bucket:bucket_water", "bucket:bucket_empty"}
}
})
-- With oil extract:
minetest.register_craft({
output = "technic:battery",
recipe = {
{"group:wood", "technic:sulfur_dust", "group:wood"},
{"technic:lead_ingot", "homedecor:oil_extract", "technic:lead_ingot"},
{"group:wood", "technic:sulfur_dust", "group:wood"},
}
})
@ -29,88 +82,240 @@ minetest.register_tool("technic:battery", {
}
})
-- x+2 + (z+2)*2
local dirtab = {
[4] = 2,
[5] = 3,
[7] = 1,
[8] = 0
}
local tube = {
insert_object = function(pos, node, stack, direction)
if direction.y == 0 then
print(minetest.pos_to_string(direction), dirtab[direction.x+2+(direction.z+2)*2], node.param2)
if direction.y == 1
or (direction.y == 0 and dirtab[direction.x+2+(direction.z+2)*2] == node.param2) then
return stack
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if direction.y > 0 then
if direction.y == 0 then
return inv:add_item("src", stack)
else
return inv:add_item("dst", stack)
end
end,
can_insert = function(pos, node, stack, direction)
if direction.y == 0 then
print(minetest.pos_to_string(direction), dirtab[direction.x+2+(direction.z+2)*2], node.param2)
if direction.y == 1
or (direction.y == 0 and dirtab[direction.x+2+(direction.z+2)*2] == node.param2) then
return false
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if direction.y > 0 then
if direction.y == 0 then
if meta:get_int("split_src_stacks") == 1 then
stack = stack:peek_item(1)
end
return inv:room_for_item("src", stack)
else
if meta:get_int("split_dst_stacks") == 1 then
stack = stack:peek_item(1)
end
return inv:room_for_item("dst", stack)
end
end,
connect_sides = {left=1, right=1, back=1, top=1, bottom=1},
connect_sides = {left=1, right=1, back=1, top=1},
}
local function add_on_off_buttons(meta, ltier, charge_percent)
local formspec = ""
if ltier == "mv" or ltier == "hv" then
formspec = "image[1,1;1,2;technic_power_meter_bg.png"
.."^[lowpart:"..charge_percent
..":technic_power_meter_fg.png]"..
fs_helpers.cycling_button(
meta,
"image_button[3,2.0;1,0.6",
"split_src_stacks",
{
pipeworks.button_off,
pipeworks.button_on
}
).."label[3.9,2.01;Allow splitting incoming 'charge' stacks from tubes]"..
fs_helpers.cycling_button(
meta,
"image_button[3,2.5;1,0.6",
"split_dst_stacks",
{
pipeworks.button_off,
pipeworks.button_on
}
).."label[3.9,2.51;Allow splitting incoming 'discharge' stacks]"
end
return formspec
end
function technic.register_battery_box(data)
local tier = data.tier
local ltier = string.lower(tier)
local formspec =
"invsize[8,9;]"..
"size[8,9]"..
"image[1,1;1,2;technic_power_meter_bg.png]"..
"list[current_name;src;3,1;1,1;]"..
"list[context;src;3,1;1,1;]"..
"image[4,1;1,1;technic_battery_reload.png]"..
"list[current_name;dst;5,1;1,1;]"..
"list[context;dst;5,1;1,1;]"..
"label[0,0;"..S("%s Battery Box"):format(tier).."]"..
"label[3,0;"..S("Charge").."]"..
"label[5,0;"..S("Discharge").."]"..
"label[1,3;"..S("Power level").."]"..
"list[current_player;main;0,5;8,4;]"
"list[current_player;main;0,5;8,4;]"..
"listring[context;dst]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"
if digilines_path then
formspec = formspec.."button[0.6,3.7;2,1;edit_channel;edit Channel]"
end
if data.upgrade then
formspec = formspec..
"list[current_name;upgrade1;3.5,3;1,1;]"..
"list[current_name;upgrade2;4.5,3;1,1;]"..
"label[3.5,4;"..S("Upgrade Slots").."]"
"list[context;upgrade1;3.5,3;1,1;]"..
"list[context;upgrade2;4.5,3;1,1;]"..
"label[3.5,4;"..S("Upgrade Slots").."]"..
"listring[context;upgrade1]"..
"listring[current_player;main]"..
"listring[context;upgrade2]"..
"listring[current_player;main]"
end
local run = function(pos, node)
local below = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z})
local meta = minetest.get_meta(pos)
if not technic.is_tier_cable(below.name, tier) then
meta:set_string("infotext", S("%s Battery Box Has No Network"):format(tier))
return
end
local eu_input = meta:get_int(tier.."_EU_input")
local current_charge = meta:get_int("internal_EU_charge")
local EU_upgrade, tube_upgrade = 0, 0
if data.upgrade then
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
end
local max_charge = data.max_charge * (1 + EU_upgrade / 10)
-- Charge/discharge the battery with the input EUs
if eu_input >= 0 then
current_charge = math.min(current_charge + eu_input, max_charge)
else
current_charge = math.max(current_charge + eu_input, 0)
end
-- Charging/discharging tools here
local tool_full, tool_empty
current_charge, tool_full = technic.charge_tools(meta,
current_charge, data.charge_step)
current_charge, tool_empty = technic.discharge_tools(meta,
current_charge, data.discharge_step,
max_charge)
if data.tube then
local inv = meta:get_inventory()
technic.handle_machine_pipeworks(pos, tube_upgrade,
function(pos, x_velocity, z_velocity)
if tool_full and not inv:is_empty("src") then
technic.send_items(pos, x_velocity, z_velocity, "src")
elseif tool_empty and not inv:is_empty("dst") then
technic.send_items(pos, x_velocity, z_velocity, "dst")
end
end)
end
-- We allow batteries to charge on less than the demand
meta:set_int(tier.."_EU_demand",
math.min(data.charge_rate, max_charge - current_charge))
meta:set_int(tier.."_EU_supply",
math.min(data.discharge_rate, current_charge))
meta:set_int("internal_EU_charge", current_charge)
-- Select node textures
local charge_count = math.ceil((current_charge / max_charge) * 8)
charge_count = math.min(charge_count, 8)
charge_count = math.max(charge_count, 0)
local last_count = meta:get_float("last_side_shown")
if charge_count ~= last_count then
technic.swap_node(pos,"technic:"..ltier.."_battery_box"..charge_count)
meta:set_float("last_side_shown", charge_count)
end
local charge_percent = math.floor(current_charge / max_charge * 100)
meta:set_string("formspec", formspec..add_on_off_buttons(meta, ltier, charge_percent))
local infotext = S("@1 Battery Box: @2 / @3", tier,
technic.EU_string(current_charge),
technic.EU_string(max_charge))
if eu_input == 0 then
infotext = S("%s Idle"):format(infotext)
end
meta:set_string("infotext", infotext)
end
for i = 0, 8 do
local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}
local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, ["technic_"..ltier]=1}
if i ~= 0 then
groups.not_in_creative_inventory = 1
end
if data.tube then
groups.tubedevice = 1
groups.tubedevice_receiver = 1
end
local top_tex = "technic_"..ltier.."_battery_box_top.png"..tube_entry
local front_tex = "technic_"..ltier.."_battery_box_front.png^technic_power_meter"..i..".png"
local side_tex = "technic_"..ltier.."_battery_box_side.png"..tube_entry
local bottom_tex = "technic_"..ltier.."_battery_box_bottom.png"..cable_entry
if ltier == "lv" then
top_tex = "technic_"..ltier.."_battery_box_top.png"
front_tex = "technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png"
side_tex = "technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png"
end
minetest.register_node("technic:"..ltier.."_battery_box"..i, {
description = S("%s Battery Box"):format(tier),
tiles = {"technic_"..ltier.."_battery_box_top.png",
"technic_"..ltier.."_battery_box_bottom.png",
"technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png",
"technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png",
"technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png",
"technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png"},
tiles = {
top_tex,
bottom_tex,
side_tex,
side_tex,
side_tex,
front_tex},
groups = groups,
connect_sides = {"bottom"},
tube = data.tube and tube or nil,
paramtype2 = "facedir",
sounds = default.node_sound_wood_defaults(),
drop = "technic:"..ltier.."_battery_box0",
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local EU_upgrade, tube_upgrade = 0, 0
if data.upgrade then
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
end
local max_charge = data.max_charge * (1 + EU_upgrade / 10)
local charge = meta:get_int("internal_EU_charge")
local cpercent = math.floor(charge / max_charge * 100)
local inv = meta:get_inventory()
local node = minetest.get_node(pos)
meta:set_string("infotext", S("%s Battery Box"):format(tier))
meta:set_string("formspec", formspec)
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_int(tier.."_EU_demand", 0)
meta:set_int(tier.."_EU_supply", 0)
meta:set_int(tier.."_EU_input", 0)
@ -124,93 +329,63 @@ function technic.register_battery_box(data)
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
technic_run = run,
on_rotate = screwdriver.rotate_simple,
after_place_node = data.tube and pipeworks.after_place,
after_dig_node = technic.machine_after_dig_node,
on_receive_fields = function(pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
local nodename = minetest.get_node(pos).name
if fields.edit_channel then
minetest.show_formspec(sender:get_player_name(),
"technic:battery_box_edit_channel"..minetest.pos_to_string(pos),
"field[channel;Digiline Channel;"..meta:get_string("channel").."]")
elseif fields["fs_helpers_cycling:0:split_src_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_dst_stacks"] then
local meta = minetest.get_meta(pos)
if not pipeworks.may_configure(pos, sender) then return end
fs_helpers.on_receive_fields(pos, fields)
local EU_upgrade, tube_upgrade = 0, 0
if data.upgrade then
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
end
local max_charge = data.max_charge * (1 + EU_upgrade / 10)
local charge = meta:get_int("internal_EU_charge")
local cpercent = math.floor(charge / max_charge * 100)
meta:set_string("formspec", formspec..add_on_off_buttons(meta, ltier, cpercent))
end
end,
digiline = {
receptor = {action = function() end},
effector = {
action = function(pos, node, channel, msg)
if msg ~= "GET" and msg ~= "get" then
return
end
local meta = minetest.get_meta(pos)
if channel ~= meta:get_string("channel") then
return
end
local inv = meta:get_inventory()
digilines.receptor_send(pos, digilines.rules.default, channel, {
demand = meta:get_int(tier.."_EU_demand"),
supply = meta:get_int(tier.."_EU_supply"),
input = meta:get_int(tier.."_EU_input"),
charge = meta:get_int("internal_EU_charge"),
max_charge = data.max_charge * (1 + technic.handle_machine_upgrades(meta) / 10),
src = inv:get_stack("src", 1):to_table(),
dst = inv:get_stack("dst", 1):to_table(),
upgrade1 = inv:get_stack("upgrade1", 1):to_table(),
upgrade2 = inv:get_stack("upgrade2", 1):to_table()
})
end
},
},
})
end
minetest.register_abm({
nodenames = {"technic:"..ltier.."_battery_box0", "technic:"..ltier.."_battery_box1",
"technic:"..ltier.."_battery_box2", "technic:"..ltier.."_battery_box3",
"technic:"..ltier.."_battery_box4", "technic:"..ltier.."_battery_box5",
"technic:"..ltier.."_battery_box6", "technic:"..ltier.."_battery_box7",
"technic:"..ltier.."_battery_box8"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local eu_input = meta:get_int(tier.."_EU_input")
local current_charge = meta:get_int("internal_EU_charge")
-- Power off automatically if no longer connected to a switching station
technic.switching_station_timeout_count(pos, tier)
local EU_upgrade, tube_upgrade = 0, 0
if data.upgrade then
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
end
local max_charge = data.max_charge * (1 + EU_upgrade / 10)
-- Charge/discharge the battery with the input EUs
if eu_input >= 0 then
current_charge = math.min(current_charge + eu_input, max_charge)
else
current_charge = math.max(current_charge + eu_input, 0)
end
-- Charging/discharging tools here
local tool_full, tool_empty
current_charge, tool_full = technic.charge_tools(meta,
current_charge, data.charge_step)
current_charge, tool_empty = technic.discharge_tools(meta,
current_charge, data.discharge_step,
max_charge)
if data.tube then
local inv = meta:get_inventory()
technic.handle_machine_pipeworks(pos, tube_upgrade,
function(pos, x_velocity, z_velocity)
if tool_full and not inv:is_empty("src") then
technic.send_items(pos, x_velocity, z_velocity, "src")
elseif tool_empty and not inv:is_empty("dst") then
technic.send_items(pos, x_velocity, z_velocity, "dst")
end
end)
end
-- We allow batteries to charge on less than the demand
meta:set_int(tier.."_EU_demand",
math.min(data.charge_rate, max_charge - current_charge))
meta:set_int(tier.."_EU_supply",
math.min(data.discharge_rate, current_charge))
meta:set_int("internal_EU_charge", current_charge)
-- Select node textures
local charge_count = math.ceil((current_charge / max_charge) * 8)
charge_count = math.min(charge_count, 8)
charge_count = math.max(charge_count, 0)
local last_count = meta:get_float("last_side_shown")
if charge_count ~= last_count then
technic.swap_node(pos,"technic:"..ltier.."_battery_box"..charge_count)
meta:set_float("last_side_shown", charge_count)
end
local charge_percent = math.floor(current_charge / max_charge * 100)
meta:set_string("formspec",
formspec..
"image[1,1;1,2;technic_power_meter_bg.png"
.."^[lowpart:"..charge_percent
..":technic_power_meter_fg.png]")
local infotext = S("%s Battery Box: %d/%d"):format(tier,
current_charge, max_charge)
if eu_input == 0 then
infotext = S("%s Idle"):format(infotext)
end
meta:set_string("infotext", infotext)
end
})
-- Register as a battery type
-- Battery type machines function as power reservoirs and can both receive and give back power
for i = 0, 8 do
@ -219,26 +394,41 @@ function technic.register_battery_box(data)
end -- End registration
minetest.register_on_player_receive_fields(
function(player, formname, fields)
if formname:sub(1, 32) ~= "technic:battery_box_edit_channel" or
not fields.channel then
return
end
local pos = minetest.string_to_pos(formname:sub(33))
local plname = player:get_player_name()
if minetest.is_protected(pos, plname) then
minetest.record_protection_violation(pos, plname)
return
end
local meta = minetest.get_meta(pos)
meta:set_string("channel", fields.channel)
end
)
function technic.charge_tools(meta, batt_charge, charge_step)
local inv = meta:get_inventory()
if inv:is_empty("src") then
return batt_charge, false
end
local srcstack = inv:get_stack("src", 1)
local src_stack = inv:get_stack("src", 1)
local toolname = srcstack:get_name()
if not technic.power_tools[toolname] then
local tool_name = src_stack:get_name()
if not technic.power_tools[tool_name] then
return batt_charge, false
end
-- Set meta data for the tool if it didn't do it itself
src_meta = minetest.deserialize(srcstack:get_metadata())
src_meta = src_meta or {}
local src_meta = minetest.deserialize(src_stack:get_metadata()) or {}
if not src_meta.charge then
src_meta.charge = 0
end
-- Do the charging
local item_max_charge = technic.power_tools[toolname]
local item_max_charge = technic.power_tools[tool_name]
local tool_charge = src_meta.charge
if tool_charge >= item_max_charge then
return batt_charge, true
@ -249,10 +439,10 @@ function technic.charge_tools(meta, batt_charge, charge_step)
charge_step = math.min(charge_step, item_max_charge - tool_charge)
tool_charge = tool_charge + charge_step
batt_charge = batt_charge - charge_step
technic.set_RE_wear(srcstack, tool_charge, item_max_charge)
technic.set_RE_wear(src_stack, tool_charge, item_max_charge)
src_meta.charge = tool_charge
srcstack:set_metadata(minetest.serialize(src_meta))
inv:set_stack("src", 1, srcstack)
src_stack:set_metadata(minetest.serialize(src_meta))
inv:set_stack("src", 1, src_stack)
return batt_charge, (tool_charge == item_max_charge)
end

View File

@ -1,175 +1,286 @@
local S = technic.getter
technic.cables = {}
local cable_tier = {}
function technic.register_cable(tier, size)
local ltier = string.lower(tier)
for x1 = 0, 1 do
for x2 = 0, 1 do
for y1 = 0, 1 do
for y2 = 0, 1 do
for z1 = 0, 1 do
for z2 = 0, 1 do
local id = technic.get_cable_id({x1, x2, y1, y2, z1, z2})
technic.cables["technic:"..ltier.."_cable"..id] = tier
local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}
if id ~= 0 then
groups.not_in_creative_inventory = 1
end
minetest.register_node("technic:"..ltier.."_cable"..id, {
description = S("%s Cable"):format(tier),
tiles = {"technic_"..ltier.."_cable.png"},
inventory_image = "technic_"..ltier.."_cable_wield.png",
wield_image = "technic_"..ltier.."_cable_wield.png",
groups = groups,
sounds = default.node_sound_wood_defaults(),
drop = "technic:"..ltier.."_cable0",
paramtype = "light",
sunlight_propagates = true,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = technic.gen_cable_nodebox(x1, y1, z1, x2, y2, z2, size)
},
on_construct = function()
technic.networks = {}
end,
on_destruct = function()
technic.networks = {}
end,
after_place_node = function(pos)
local node = minetest.get_node(pos)
technic.update_cables(pos, technic.get_cable_tier(node.name))
end,
after_dig_node = function(pos, oldnode)
local tier = technic.get_cable_tier(oldnode.name)
technic.update_cables(pos, tier, true)
end
})
end
end
end
end
end
end
function technic.is_tier_cable(name, tier)
return cable_tier[name] == tier
end
minetest.register_on_placenode(function(pos, node)
for tier, machine_list in pairs(technic.machines) do
if machine_list[node.name] ~= nil then
technic.update_cables(pos, tier, true)
technic.networks = {}
end
end
end)
minetest.register_on_dignode(function(pos, node)
for tier, machine_list in pairs(technic.machines) do
if machine_list[node.name] ~= nil then
technic.update_cables(pos, tier, true)
technic.networks = {}
end
end
end)
function technic.get_cable_id(links)
return (links[6] * 1) + (links[5] * 2)
+ (links[4] * 4) + (links[3] * 8)
+ (links[2] * 16) + (links[1] * 32)
function technic.get_cable_tier(name)
return cable_tier[name]
end
function technic.update_cables(pos, tier, no_set, secondrun)
local link_positions = {
local function check_connections(pos)
-- Build a table of all machines
local machines = {}
for tier,list in pairs(technic.machines) do
for k,v in pairs(list) do
machines[k] = v
end
end
local connections = {}
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, y=pos.y+1, z=pos.z},
{x=pos.x, y=pos.y-1, z=pos.z},
{x=pos.x, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1}}
for _,connected_pos in pairs(positions) do
local name = minetest.get_node(connected_pos).name
if machines[name] or technic.get_cable_tier(name) then
table.insert(connections,connected_pos)
end
end
return connections
end
local links = {0, 0, 0, 0, 0, 0}
local function clear_networks(pos)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
local placed = node.name ~= "air"
local positions = check_connections(pos)
if #positions < 1 then return end
local dead_end = #positions == 1
for _,connected_pos in pairs(positions) do
local net = technic.cables[minetest.hash_node_position(connected_pos)]
if net and technic.networks[net] then
if dead_end and placed then
-- Dead end placed, add it to the network
-- Get the network
local network_id = technic.cables[minetest.hash_node_position(positions[1])]
if not network_id then
-- We're evidently not on a network, nothing to add ourselves to
return
end
local sw_pos = minetest.get_position_from_hash(network_id)
sw_pos.y = sw_pos.y + 1
local network = technic.networks[network_id]
local tier = network.tier
for i, link_pos in pairs(link_positions) do
local connect_type = technic.cables_should_connect(pos, link_pos, tier)
if connect_type then
links[i] = 1
-- Have cables next to us update theirselves,
-- but only once. (We don't want to update the entire
-- network or start an infinite loop of updates)
if not secondrun and connect_type == "cable" then
technic.update_cables(link_pos, tier, false, true)
-- Actually add it to the (cached) network
-- This is similar to check_node_subp
technic.cables[minetest.hash_node_position(pos)] = network_id
pos.visited = 1
if technic.is_tier_cable(name, tier) then
table.insert(network.all_nodes,pos)
elseif technic.machines[tier][node.name] then
meta:set_string(tier.."_network",minetest.pos_to_string(sw_pos))
if technic.machines[tier][node.name] == technic.producer then
table.insert(network.PR_nodes,pos)
elseif technic.machines[tier][node.name] == technic.receiver then
table.insert(network.RE_nodes,pos)
elseif technic.machines[tier][node.name] == technic.producer_receiver then
table.insert(network.PR_nodes,pos)
table.insert(network.RE_nodes,pos)
elseif technic.machines[tier][node.name] == "SPECIAL" and
(pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) and
from_below then
table.insert(network.SP_nodes,pos)
elseif technic.machines[tier][node.name] == technic.battery then
table.insert(network.BA_nodes,pos)
end
end
elseif dead_end and not placed then
-- Dead end removed, remove it from the network
-- Get the network
local network_id = technic.cables[minetest.hash_node_position(positions[1])]
if not network_id then
-- We're evidently not on a network, nothing to add ourselves to
return
end
local network = technic.networks[network_id]
-- Search for and remove machine
technic.cables[minetest.hash_node_position(pos)] = nil
for tblname,table in pairs(network) do
if tblname ~= "tier" then
for machinenum,machine in pairs(table) do
if machine.x == pos.x
and machine.y == pos.y
and machine.z == pos.z then
table[machinenum] = nil
end
end
end
end
else
-- Not a dead end, so the whole network needs to be recalculated
for _,v in pairs(technic.networks[net].all_nodes) do
local pos1 = minetest.hash_node_position(v)
technic.cables[pos1] = nil
end
technic.networks[net] = nil
end
end
end
-- We don't want to set ourselves if we have been removed or we are
-- updating a machine
if not no_set then
minetest.set_node(pos, {name="technic:"..string.lower(tier)
.."_cable"..technic.get_cable_id(links)})
end
function technic.register_cable(tier, size)
local ltier = string.lower(tier)
cable_tier["technic:"..ltier.."_cable"] = tier
local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
["technic_"..ltier.."_cable"] = 1}
local node_box = {
type = "connected",
fixed = {-size, -size, -size, size, size, size},
connect_top = {-size, -size, -size, size, 0.5, size}, -- y+
connect_bottom = {-size, -0.5, -size, size, size, size}, -- y-
connect_front = {-size, -size, -0.5, size, size, size}, -- z-
connect_back = {-size, -size, size, size, size, 0.5 }, -- z+
connect_left = {-0.5, -size, -size, size, size, size}, -- x-
connect_right = {-size, -size, -size, 0.5, size, size}, -- x+
}
minetest.register_node("technic:"..ltier.."_cable", {
description = S("%s Cable"):format(tier),
tiles = {"technic_"..ltier.."_cable.png"},
inventory_image = "technic_"..ltier.."_cable_wield.png",
wield_image = "technic_"..ltier.."_cable_wield.png",
groups = groups,
sounds = default.node_sound_wood_defaults(),
drop = "technic:"..ltier.."_cable",
paramtype = "light",
sunlight_propagates = true,
drawtype = "nodebox",
node_box = node_box,
connects_to = {"group:technic_"..ltier.."_cable",
"group:technic_"..ltier, "group:technic_all_tiers"},
on_construct = clear_networks,
on_destruct = clear_networks,
})
local xyz = {
["-x"] = 1,
["-y"] = 2,
["-z"] = 3,
["x"] = 4,
["y"] = 5,
["z"] = 6,
}
local notconnects = {
[1] = "left",
[2] = "bottom",
[3] = "front",
[4] = "right",
[5] = "top",
[6] = "back",
}
local function s(p)
if p:find("-") then
return p:sub(2)
else
return "-"..p
end
end
for p, i in pairs(xyz) do
local def = {
description = S("%s Cable Plate"):format(tier),
tiles = {"technic_"..ltier.."_cable.png"},
groups = table.copy(groups),
sounds = default.node_sound_wood_defaults(),
drop = "technic:"..ltier.."_cable_plate_1",
paramtype = "light",
sunlight_propagates = true,
drawtype = "nodebox",
node_box = table.copy(node_box),
connects_to = {"group:technic_"..ltier.."_cable",
"group:technic_"..ltier, "group:technic_all_tiers"},
on_construct = clear_networks,
on_destruct = clear_networks,
}
def.node_box.fixed = {
{-size, -size, -size, size, size, size},
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}
}
def.node_box.fixed[1][xyz[p]] = 7/16 * (i-3.5)/math.abs(i-3.5)
def.node_box.fixed[2][xyz[s(p)]] = 3/8 * (i-3.5)/math.abs(i-3.5)
def.node_box["connect_"..notconnects[i]] = nil
if i == 1 then
def.on_place = function(itemstack, placer, pointed_thing)
local pointed_thing_diff = vector.subtract(pointed_thing.above, pointed_thing.under)
local num
local changed
for k, v in pairs(pointed_thing_diff) do
if v ~= 0 then
changed = k
num = xyz[s(tostring(v):sub(-2, -2)..k)]
break
end
end
local crtl = placer:get_player_control()
if (crtl.aux1 or crtl.sneak) and not (crtl.aux1 and crtl.sneak) then
local fine_pointed = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
fine_pointed = vector.subtract(fine_pointed, pointed_thing.above)
fine_pointed[changed] = nil
local ps = {}
for p, _ in pairs(fine_pointed) do
ps[#ps+1] = p
end
local bigger = (math.abs(fine_pointed[ps[1]]) > math.abs(fine_pointed[ps[2]]) and ps[1]) or ps[2]
if math.abs(fine_pointed[bigger]) < 0.3 then
num = num + 3
num = (num <= 6 and num) or num - 6
else
num = xyz[((fine_pointed[bigger] < 0 and "-") or "") .. bigger]
end
end
minetest.set_node(pointed_thing.above, {name = "technic:"..ltier.."_cable_plate_"..num})
if not (creative and creative.is_enabled_for(placer)) then
itemstack:take_item()
end
return itemstack
end
else
def.groups.not_in_creative_inventory = 1
end
def.on_rotate = function(pos, node, user, mode, new_param2)
local dir = 0
if mode == screwdriver.ROTATE_FACE then -- left-click
dir = 1
elseif mode == screwdriver.ROTATE_AXIS then -- right-click
dir = -1
end
local num = tonumber(node.name:sub(-1))
num = num + dir
num = (num >= 1 and num) or num + 6
num = (num <= 6 and num) or num - 6
minetest.swap_node(pos, {name = "technic:"..ltier.."_cable_plate_"..num})
end
minetest.register_node("technic:"..ltier.."_cable_plate_"..i, def)
cable_tier["technic:"..ltier.."_cable_plate_"..i] = tier
end
local c = "technic:"..ltier.."_cable"
minetest.register_craft({
output = "technic:"..ltier.."_cable_plate_1 5",
recipe = {
{"", "", c},
{c , c , c},
{"", "", c},
}
})
minetest.register_craft({
output = c,
recipe = {
{"technic:"..ltier.."_cable_plate_1"},
}
})
end
function technic.is_tier_cable(name, tier)
return technic.cables[name] and technic.cables[name] == tier
local function clear_nets_if_machine(pos, node)
for tier, machine_list in pairs(technic.machines) do
if machine_list[node.name] ~= nil then
return clear_networks(pos)
end
end
end
function technic.get_cable_tier(name)
return technic.cables[name]
end
function technic.cables_should_connect(pos1, pos2, tier)
local name = minetest.get_node(pos2).name
if technic.is_tier_cable(name, tier) then
return "cable"
elseif technic.machines[tier][name] then
return "machine"
end
return false
end
function technic.gen_cable_nodebox(x1, y1, z1, x2, y2, z2, size)
-- Nodeboxes
local box_center = {-size, -size, -size, size, size, size}
local box_y1 = {-size, -size, -size, size, 0.5, size} -- y+
local box_x1 = {-size, -size, -size, 0.5, size, size} -- x+
local box_z1 = {-size, -size, size, size, size, 0.5} -- z+
local box_z2 = {-size, -size, -0.5, size, size, size} -- z-
local box_y2 = {-size, -0.5, -size, size, size, size} -- y-
local box_x2 = {-0.5, -size, -size, size, size, size} -- x-
local box = {box_center}
if x1 == 1 then
table.insert(box, box_x1)
end
if y1 == 1 then
table.insert(box, box_y1)
end
if z1 == 1 then
table.insert(box, box_z1)
end
if x2 == 1 then
table.insert(box, box_x2)
end
if y2 == 1 then
table.insert(box, box_y2)
end
if z2 == 1 then
table.insert(box, box_z2)
end
return box
end
minetest.register_on_placenode(clear_nets_if_machine)
minetest.register_on_dignode(clear_nets_if_machine)

View File

@ -0,0 +1,8 @@
local S = technic.getter
function technic.register_centrifuge(data)
data.typename = "separating"
data.machine_name = "centrifuge"
data.machine_desc = S("%s Centrifuge")
technic.register_base_machine(data)
end

View File

@ -0,0 +1,40 @@
local S = technic.getter
technic.register_recipe_type("separating", {
description = S("Separating"),
output_size = 2,
})
function technic.register_separating_recipe(data)
data.time = data.time or 10
technic.register_recipe("separating", data)
end
local recipes = {
{ "technic:bronze_dust 4", "technic:copper_dust 3", "technic:tin_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:chernobylite_dust", "default:sand", "technic:uranium3_dust" },
{ "default:dirt 4", "default:sand", "default:gravel", "default:clay_lump 2" },
}
local function uranium_dust(p)
return "technic:uranium"..(p == 7 and "" or p).."_dust"
end
for p = 1, 34 do
table.insert(recipes, { uranium_dust(p).." 2", uranium_dust(p-1), uranium_dust(p+1) })
end
if minetest.get_modpath("bushes_classic") then
for _, berry in ipairs({ "blackberry", "blueberry", "gooseberry", "raspberry", "strawberry" }) do
table.insert(recipes, { "bushes:"..berry.."_bush", "default:stick 20", "bushes:"..berry.." 4" })
end
end
if minetest.get_modpath("farming") then
table.insert(recipes, { "farming:wheat 4", "farming:seed_wheat 3", "default:dry_shrub 1" })
end
for _, data in pairs(recipes) do
technic.register_separating_recipe({ input = { data[1] }, output = { data[2], data[3], data[4] } })
end

View File

@ -1,41 +1,64 @@
local S = technic.getter
-- handles the machine upgrades every tick
function technic.handle_machine_upgrades(meta)
-- Get the names of the upgrades
local inv = meta:get_inventory()
local upg_item1
local upg_item2
local srcstack = inv:get_stack("upgrade1", 1)
if srcstack then
upg_item1 = srcstack:to_table()
end
local upg_item1 = srcstack and srcstack:get_name()
srcstack = inv:get_stack("upgrade2", 1)
if srcstack then
upg_item2 = srcstack:to_table()
end
local upg_item2 = srcstack and srcstack:get_name()
-- Save some power by installing battery upgrades.
-- Tube loading speed can be upgraded using control logic units.
local EU_upgrade = 0
local tube_upgrade = 0
if upg_item1 then
if upg_item1.name == "technic:battery" then
EU_upgrade = EU_upgrade + 1
elseif upg_item1.name == "technic:control_logic_unit" then
tube_upgrade = tube_upgrade + 1
end
if upg_item1 == "technic:control_logic_unit" then
tube_upgrade = tube_upgrade + 1
elseif upg_item1 == "technic:battery" then
EU_upgrade = EU_upgrade + 1
end
if upg_item2 then
if upg_item2.name == "technic:battery" then
EU_upgrade = EU_upgrade + 1
elseif upg_item2.name == "technic:control_logic_unit" then
tube_upgrade = tube_upgrade + 1
end
if upg_item2 == "technic:control_logic_unit" then
tube_upgrade = tube_upgrade + 1
elseif upg_item2 == "technic:battery" then
EU_upgrade = EU_upgrade + 1
end
return EU_upgrade, tube_upgrade
end
-- handles the machine upgrades when set or removed
local function on_machine_upgrade(meta, stack)
local stack_name = stack:get_name()
if stack_name == "default:chest" then
meta:set_int("public", 1)
return 1
elseif stack_name ~= "technic:control_logic_unit"
and stack_name ~= "technic:battery" then
return 0
end
return 1
end
-- something is about to be removed
local function on_machine_downgrade(meta, stack, list)
if stack:get_name() == "default:chest" then
local inv = meta:get_inventory()
local upg1, upg2 = inv:get_stack("upgrade1", 1), inv:get_stack("upgrade2", 1)
-- only set 0 if theres not a nother chest in the other list too
if (not upg1 or not upg2 or upg1:get_name() ~= upg2:get_name()) then
meta:set_int("public", 0)
end
end
return 1
end
function technic.send_items(pos, x_velocity, z_velocity, output_name)
-- Send items on their way in the pipe system.
@ -52,10 +75,7 @@ function technic.send_items(pos, x_velocity, z_velocity, output_name)
local item0 = stack:to_table()
if item0 then
item0["count"] = "1"
local item1 = pipeworks.tube_item({x=pos.x, y=pos.y, z=pos.z}, item0)
item1:get_luaentity().start_pos = {x=pos.x, y=pos.y, z=pos.z}
item1:setvelocity({x=x_velocity, y=0, z=z_velocity})
item1:setacceleration({x=0, y=0, z=0})
technic.tube_inject_item(pos, pos, vector.new(x_velocity, 0, z_velocity), item0)
stack:take_item(1)
inv:set_stack(output_name, i, stack)
return
@ -71,15 +91,15 @@ function technic.smelt_item(meta, result, speed)
if meta:get_int("cook_time") < result.time / speed then
return
end
local result = minetest.get_craft_result({method = "cooking", width = 1, items = inv:get_list("src")})
local result
local afterfuel
result, afterfuel = minetest.get_craft_result({method = "cooking", width = 1, items = inv:get_list("src")})
if result and result.item then
meta:set_int("cook_time", 0)
-- check if there's room for output in "dst" list
if inv:room_for_item("dst", result.item) then
srcstack = inv:get_stack("src", 1)
srcstack:take_item()
inv:set_stack("src", 1, srcstack)
inv:set_stack("src", 1, afterfuel.items[1])
inv:add_item("dst", result.item)
end
end
@ -104,12 +124,11 @@ function technic.handle_machine_pipeworks(pos, tube_upgrade, send_function)
if node.param2 == 0 then pos1.x = pos1.x + 1 x_velocity = 1 end
local output_tube_connected = false
local meta1 = minetest.get_meta(pos1)
if meta1:get_int("tubelike") == 1 then
local node1 = minetest.get_node(pos1)
if minetest.get_item_group(node1.name, "tubedevice") > 0 then
output_tube_connected = true
end
tube_time = meta:get_int("tube_time")
tube_time = tube_time + tube_upgrade
local tube_time = meta:get_int("tube_time") + tube_upgrade
if tube_time >= 2 then
tube_time = 0
if output_tube_connected then
@ -119,39 +138,77 @@ function technic.handle_machine_pipeworks(pos, tube_upgrade, send_function)
meta:set_int("tube_time", tube_time)
end
function technic.machine_can_dig(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if not inv:is_empty("src") or not inv:is_empty("dst") or
not inv:is_empty("upgrade1") or not inv:is_empty("upgrade2") then
minetest.chat_send_player(player:get_player_name(),
S("Machine cannot be removed because it is not empty"))
if not inv:is_empty("src") or not inv:is_empty("dst") then
if player then
minetest.chat_send_player(player:get_player_name(),
S("Machine cannot be removed because it is not empty"))
end
return false
else
return true
end
return true
end
function technic.machine_after_dig_node(pos, oldnode, oldmetadata, player)
if oldmetadata.inventory then
if oldmetadata.inventory.upgrade1 and oldmetadata.inventory.upgrade1[1] then
local stack = ItemStack(oldmetadata.inventory.upgrade1[1])
if not stack:is_empty() then
minetest.add_item(pos, stack)
end
end
if oldmetadata.inventory.upgrade2 and oldmetadata.inventory.upgrade2[1] then
local stack = ItemStack(oldmetadata.inventory.upgrade2[1])
if not stack:is_empty() then
minetest.add_item(pos, stack)
end
end
end
if minetest.registered_nodes[oldnode.name].tube then
pipeworks.after_dig(pos, oldnode, oldmetadata, player)
end
end
local function inv_change(pos, player, count)
if minetest.is_protected(pos, player:get_player_name()) then
minetest.chat_send_player(player:get_player_name(),
S("Inventory move disallowed due to protection"))
local function inv_change(pos, player, count, from_list, to_list, stack)
local playername = player:get_player_name()
local meta = minetest.get_meta(pos);
local public = (meta:get_int("public") == 1)
local to_upgrade = to_list == "upgrade1" or to_list == "upgrade2"
local from_upgrade = from_list == "upgrade1" or from_list == "upgrade2"
if (not public or to_upgrade or from_upgrade) and minetest.is_protected(pos, playername) then
minetest.chat_send_player(playername, S("Inventory move disallowed due to protection"))
return 0
end
if to_upgrade then
-- only place a single item into it, if it's empty
local empty = meta:get_inventory():is_empty(to_list)
if empty then
return on_machine_upgrade(meta, stack)
end
return 0
elseif from_upgrade then
-- only called on take (not move)
on_machine_downgrade(meta, stack, from_list)
end
return count
end
function technic.machine_inventory_put(pos, listname, index, stack, player)
return inv_change(pos, player, stack:get_count())
return inv_change(pos, player, stack:get_count(), nil, listname, stack)
end
function technic.machine_inventory_take(pos, listname, index, stack, player)
return inv_change(pos, player, stack:get_count())
return inv_change(pos, player, stack:get_count(), listname, nil, stack)
end
function technic.machine_inventory_move(pos, from_list, from_index,
to_list, to_index, count, player)
return inv_change(pos, player, count)
local stack = minetest.get_meta(pos):get_inventory():get_stack(from_list, from_index)
return inv_change(pos, player, count, from_list, to_list, stack)
end

View File

@ -1,7 +1,7 @@
local S = technic.getter
technic.register_recipe_type("compressing", S("Compressing"))
technic.register_recipe_type("compressing", { description = S("Compressing") })
function technic.register_compressor_recipe(data)
data.time = data.time or 4
@ -10,14 +10,24 @@ end
local recipes = {
{"default:snowblock", "default:ice"},
{"default:sand 2", "default:sandstone"},
{"default:desert_sand", "default:desert_stone"},
{"technic:mixed_metal_ingot", "technic:composite_plate"},
{"default:copper_ingot 5", "technic:copper_plate"},
{"technic:coal_dust 4", "technic:graphite"},
{"technic:carbon_cloth", "technic:carbon_plate"},
{"technic:enriched_uranium 4", "technic:uranium_fuel"},
{"technic:uranium35_ingot 5", "technic:uranium_fuel"},
}
-- defuse the default sandstone recipe, since we have the compressor to take over in a more realistic manner
minetest.clear_craft({
output = "default:sandstone",
recipe = {
{'group:sand', 'group:sand'},
{'group:sand', 'group:sand'}
},
})
for _, data in pairs(recipes) do
technic.register_compressor_recipe({input = {data[1]}, output = data[2]})
end

View File

@ -1,35 +1,59 @@
local S = technic.getter
technic.register_recipe_type("extracting", S("Extracting"))
technic.register_recipe_type("extracting", { description = S("Extracting") })
function technic.register_extractor_recipe(data)
data.time = data.time or 4
technic.register_recipe("extracting", data)
end
local recipes = {
-- Dyes
{"technic:coal_dust", "dye:black 2"},
{"default:cactus", "dye:green 2"},
{"default:dry_shrub", "dye:brown 2"},
{"flowers:geranium", "dye:blue 2"},
{"flowers:dandelion_white", "dye:white 2"},
{"flowers:dandelion_yellow", "dye:yellow 2"},
{"flowers:tulip", "dye:orange 2"},
{"flowers:rose", "dye:red 2"},
{"flowers:viola", "dye:violet 2"},
-- Rubber
{"technic:raw_latex", "technic:rubber 3"},
{"moretrees:rubber_tree_trunk_empty", "technic:rubber"},
{"moretrees:rubber_tree_trunk", "technic:rubber"},
-- Other
{"technic:uranium 5", "technic:enriched_uranium"},
}
if minetest.get_modpath("dye") then
-- check if we are using dye or unifieddyes
local unifieddyes = minetest.get_modpath("unifieddyes")
for _, data in pairs(recipes) do
technic.register_extractor_recipe({input = {data[1]}, output = data[2]})
-- register recipes with the same crafting ratios as `dye` provides
local dye_recipes = {
{"technic:coal_dust", "dye:black 2"},
{"default:grass_1", "dye:green 1"},
{"default:dry_shrub", "dye:brown 1"},
{"default:junglegrass", "dye:green 2"},
{"default:cactus", "dye:green 4"},
{"flowers:geranium", "dye:blue 4"},
{"flowers:dandelion_white", "dye:white 4"},
{"flowers:dandelion_yellow", "dye:yellow 4"},
{"flowers:tulip", "dye:orange 4"},
{"flowers:rose", "dye:red 4"},
{"flowers:viola", "dye:violet 4"},
{"bushes:blackberry", unifieddyes and "unifieddyes:magenta_s50 4" or "dye:violet 4"},
{"bushes:blueberry", unifieddyes and "unifieddyes:magenta_s50 4" or "dye:magenta 4"},
}
for _, data in ipairs(dye_recipes) do
technic.register_extractor_recipe({input = {data[1]}, output = data[2]})
end
-- overwrite the existing crafting recipes
local dyes = {"white", "red", "yellow", "blue", "violet", "orange"}
for _, color in ipairs(dyes) do
minetest.register_craft({
type = "shapeless",
output = "dye:"..color.." 1",
recipe = {"group:flower,color_"..color},
})
end
minetest.register_craft({
type = "shapeless",
output = "dye:black 1",
recipe = {"group:coal"},
})
if unifieddyes then
minetest.register_craft({
type = "shapeless",
output = "dye:green 1",
recipe = {"default:cactus"},
})
end
end

View File

@ -1,5 +1,8 @@
local S = technic.getter
local fs_helpers = pipeworks.fs_helpers
local tube_entry = "^pipeworks_tube_connection_metallic.png"
local tube = {
insert_object = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
@ -9,49 +12,141 @@ local tube = {
can_insert = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if meta:get_int("splitstacks") == 1 then
stack = stack:peek_item(1)
end
return inv:room_for_item("src", stack)
end,
connect_sides = {left=1, right=1, back=1, top=1, bottom=1},
}
function technic.register_generator(data)
function technic.register_generator(data)
local tier = data.tier
local ltier = string.lower(tier)
local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}
local active_groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, not_in_creative_inventory=1}
local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, ["technic_"..ltier]=1}
if data.tube then
groups.tubedevice = 1
groups.tubedevice_receiver = 1
active_groups.tubedevice = 1
active_groups.tubedevice_receiver = 1
end
local active_groups = {not_in_creative_inventory = 1}
for k, v in pairs(groups) do active_groups[k] = v end
local generator_formspec =
"invsize[8,9;]"..
"size[8,9;]"..
"label[0,0;"..S("Fuel-Fired %s Generator"):format(tier).."]"..
"list[current_name;src;3,1;1,1;]"..
"image[4,1;1,1;default_furnace_fire_bg.png]"..
"list[current_player;main;0,5;8,4;]"
"list[current_player;main;0,5;8,4;]"..
"listring[]"
local desc = S("Fuel-Fired %s Generator"):format(tier)
local run = function(pos, node)
local meta = minetest.get_meta(pos)
local burn_time = meta:get_int("burn_time")
local burn_totaltime = meta:get_int("burn_totaltime")
-- If more to burn and the energy produced was used: produce some more
if burn_time > 0 then
meta:set_int(tier.."_EU_supply", data.supply)
burn_time = burn_time - 1
meta:set_int("burn_time", burn_time)
end
-- Burn another piece of fuel
if burn_time == 0 then
local inv = meta:get_inventory()
if not inv:is_empty("src") then
local fuellist = inv:get_list("src")
local fuel
local afterfuel
fuel, afterfuel = minetest.get_craft_result(
{method = "fuel", width = 1,
items = fuellist})
if not fuel or fuel.time == 0 then
meta:set_string("infotext", S("%s Out Of Fuel"):format(desc))
technic.swap_node(pos, "technic:"..ltier.."_generator")
meta:set_int(tier.."_EU_supply", 0)
return
end
meta:set_int("burn_time", fuel.time)
meta:set_int("burn_totaltime", fuel.time)
inv:set_stack("src", 1, afterfuel.items[1])
technic.swap_node(pos, "technic:"..ltier.."_generator_active")
meta:set_int(tier.."_EU_supply", data.supply)
else
technic.swap_node(pos, "technic:"..ltier.."_generator")
meta:set_int(tier.."_EU_supply", 0)
end
end
if burn_totaltime == 0 then burn_totaltime = 1 end
local percent = math.floor((burn_time / burn_totaltime) * 100)
meta:set_string("infotext", desc.." ("..percent.."%)")
local form_buttons = ""
if ltier ~= "lv" then
form_buttons = fs_helpers.cycling_button(
meta,
pipeworks.button_base,
"splitstacks",
{
pipeworks.button_off,
pipeworks.button_on
}
)..pipeworks.button_label
end
meta:set_string("formspec",
"size[8, 9]"..
"label[0, 0;"..minetest.formspec_escape(desc).."]"..
"list[current_name;src;3, 1;1, 1;]"..
"image[4, 1;1, 1;default_furnace_fire_bg.png^[lowpart:"..
(percent)..":default_furnace_fire_fg.png]"..
"list[current_player;main;0, 5;8, 4;]"..
"listring[]"..
form_buttons
)
end
local tentry = tube_entry
if ltier == "lv" then tentry = "" end
minetest.register_node("technic:"..ltier.."_generator", {
description = desc,
tiles = {"technic_"..ltier.."_generator_top.png", "technic_machine_bottom.png",
"technic_"..ltier.."_generator_side.png", "technic_"..ltier.."_generator_side.png",
"technic_"..ltier.."_generator_side.png", "technic_"..ltier.."_generator_front.png"},
tiles = {
"technic_"..ltier.."_generator_top.png"..tentry,
"technic_machine_bottom.png"..tentry,
"technic_"..ltier.."_generator_side.png"..tentry,
"technic_"..ltier.."_generator_side.png"..tentry,
"technic_"..ltier.."_generator_side.png"..tentry,
"technic_"..ltier.."_generator_front.png"
},
paramtype2 = "facedir",
groups = groups,
connect_sides = {"bottom", "back", "left", "right"},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
tube = data.tube and tube or nil,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos)
meta:set_string("infotext", desc)
meta:set_int(data.tier.."_EU_supply", 0)
meta:set_int("burn_time", 0)
meta:set_int("tube_time", 0)
meta:set_string("formspec", generator_formspec)
local form_buttons = ""
if not string.find(node.name, ":lv_") then
form_buttons = fs_helpers.cycling_button(
meta,
pipeworks.button_base,
"splitstacks",
{
pipeworks.button_off,
pipeworks.button_on
}
)..pipeworks.button_label
end
meta:set_string("formspec", generator_formspec..form_buttons)
local inv = meta:get_inventory()
inv:set_size("src", 1)
end,
@ -59,75 +154,139 @@ function technic.register_generator(data)
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
technic_run = run,
after_place_node = data.tube and pipeworks.after_place,
after_dig_node = technic.machine_after_dig_node,
on_receive_fields = function(pos, formname, fields, sender)
if not pipeworks.may_configure(pos, sender) then return end
fs_helpers.on_receive_fields(pos, fields)
local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos)
local form = generator_formspec
local form_buttons = ""
if not string.find(node.name, ":lv_") then
form_buttons = fs_helpers.cycling_button(
meta,
pipeworks.button_base,
"splitstacks",
{
pipeworks.button_off,
pipeworks.button_on
}
)..pipeworks.button_label
end
meta:set_string("formspec", generator_formspec..form_buttons)
end,
})
minetest.register_node("technic:"..ltier.."_generator_active", {
description = desc,
tiles = {"technic_"..ltier.."_generator_top.png", "technic_machine_bottom.png",
"technic_"..ltier.."_generator_side.png", "technic_"..ltier.."_generator_side.png",
"technic_"..ltier.."_generator_side.png", "technic_"..ltier.."_generator_front_active.png"},
tiles = {
"technic_"..ltier.."_generator_top.png"..tube_entry,
"technic_machine_bottom.png"..tube_entry,
"technic_"..ltier.."_generator_side.png"..tube_entry,
"technic_"..ltier.."_generator_side.png"..tube_entry,
"technic_"..ltier.."_generator_side.png"..tube_entry,
"technic_"..ltier.."_generator_front_active.png"
},
paramtype2 = "facedir",
groups = active_groups,
connect_sides = {"bottom"},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
tube = data.tube and tube or nil,
drop = "technic:"..ltier.."_generator",
can_dig = technic.machine_can_dig,
after_dig_node = technic.machine_after_dig_node,
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
})
minetest.register_abm({
nodenames = {"technic:"..ltier.."_generator", "technic:"..ltier.."_generator_active"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
technic_run = run,
technic_on_disable = function(pos, node)
local timer = minetest.get_node_timer(pos)
timer:start(1)
end,
on_timer = function(pos, node)
local meta = minetest.get_meta(pos)
local burn_time = meta:get_int("burn_time")
local burn_totaltime = meta:get_int("burn_totaltime")
-- If more to burn and the energy produced was used: produce some more
if burn_time > 0 then
meta:set_int(tier.."_EU_supply", data.supply)
burn_time = burn_time - 1
meta:set_int("burn_time", burn_time)
end
-- Burn another piece of fuel
if burn_time == 0 then
local inv = meta:get_inventory()
if not inv:is_empty("src") then
local fuellist = inv:get_list("src")
local fuel = minetest.get_craft_result(
{method = "fuel", width = 1,
items = fuellist})
if not fuel or fuel.time == 0 then
meta:set_string("infotext", S("%s Out Of Fuel"):format(desc))
technic.swap_node(pos, "technic:"..ltier.."_generator")
return
end
meta:set_int("burn_time", fuel.time)
meta:set_int("burn_totaltime", fuel.time)
local stack = inv:get_stack("src", 1)
stack:take_item()
inv:set_stack("src", 1, stack)
technic.swap_node(pos, "technic:"..ltier.."_generator_active")
meta:set_int(tier.."_EU_supply", data.supply)
else
technic.swap_node(pos, "technic:"..ltier.."_generator")
meta:set_int(tier.."_EU_supply", 0)
end
local node = minetest.get_node(pos)
-- Connected back?
if meta:get_int(tier.."_EU_timeout") > 0 then return false end
local burn_time = meta:get_int("burn_time") or 0
if burn_time <= 0 then
meta:set_int(tier.."_EU_supply", 0)
meta:set_int("burn_time", 0)
technic.swap_node(pos, "technic:"..ltier.."_generator")
return false
end
local burn_totaltime = meta:get_int("burn_totaltime") or 0
if burn_totaltime == 0 then burn_totaltime = 1 end
local percent = math.floor((burn_time / burn_totaltime) * 100)
meta:set_string("infotext", desc.." ("..percent.."%)")
meta:set_string("formspec",
"size[8, 9]"..
"label[0, 0;"..minetest.formspec_escape(desc).."]"..
"list[current_name;src;3, 1;1, 1;]"..
"image[4, 1;1, 1;default_furnace_fire_bg.png^[lowpart:"..
(percent)..":default_furnace_fire_fg.png]"..
"list[current_player;main;0, 5;8, 4;]")
end
burn_time = burn_time - 1
meta:set_int("burn_time", burn_time)
local percent = math.floor(burn_time / burn_totaltime * 100)
local form_buttons = ""
if not string.find(node.name, ":lv_") then
form_buttons = fs_helpers.cycling_button(
meta,
pipeworks.button_base,
"splitstacks",
{
pipeworks.button_off,
pipeworks.button_on
}
)..pipeworks.button_label
end
meta:set_string("formspec",
"size[8, 9]"..
"label[0, 0;"..minetest.formspec_escape(desc).."]"..
"list[current_name;src;3, 1;1, 1;]"..
"image[4, 1;1, 1;default_furnace_fire_bg.png^[lowpart:"..
(percent)..":default_furnace_fire_fg.png]"..
"list[current_player;main;0, 5;8, 4;]"..
"listring[]"..
form_buttons
)
return true
end,
on_receive_fields = function(pos, formname, fields, sender)
if not pipeworks.may_configure(pos, sender) then return end
fs_helpers.on_receive_fields(pos, fields)
local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos)
local form_buttons = ""
if not string.find(node.name, ":lv_") then
form_buttons = fs_helpers.cycling_button(
meta,
pipeworks.button_base,
"splitstacks",
{
pipeworks.button_off,
pipeworks.button_on
}
)..pipeworks.button_label
end
local burn_totaltime = meta:get_int("burn_totaltime") or 0
local burn_time = meta:get_int("burn_time")
local percent = math.floor(burn_time / burn_totaltime * 100)
meta:set_string("formspec",
"size[8, 9]"..
"label[0, 0;"..minetest.formspec_escape(desc).."]"..
"list[current_name;src;3, 1;1, 1;]"..
"image[4, 1;1, 1;default_furnace_fire_bg.png^[lowpart:"..
(percent)..":default_furnace_fire_fg.png]"..
"list[current_player;main;0, 5;8, 4;]"..
"listring[]"..
form_buttons
)
end,
})
technic.register_machine(tier, "technic:"..ltier.."_generator", technic.producer)
technic.register_machine(tier, "technic:"..ltier.."_generator_active", technic.producer)
end

View File

@ -1,7 +1,7 @@
local S = technic.getter
technic.register_recipe_type("grinding", S("Grinding"))
technic.register_recipe_type("grinding", { description = S("Grinding") })
function technic.register_grinder_recipe(data)
data.time = data.time or 3
@ -10,23 +10,42 @@ end
local recipes = {
-- Dusts
{"default:coal_lump", "technic:coal_dust 2"},
{"default:copper_lump", "technic:copper_dust 2"},
{"default:desert_stone", "default:desert_sand"},
{"default:gold_lump", "technic:gold_dust 2"},
{"default:iron_lump", "technic:wrought_iron_dust 2"},
{"moreores:mithril_lump", "technic:mithril_dust 2"},
{"moreores:silver_lump", "technic:silver_dust 2"},
{"moreores:tin_lump", "technic:tin_dust 2"},
{"technic:chromium_lump", "technic:chromium_dust 2"},
{"technic:zinc_lump", "technic:zinc_dust 2"},
{"default:coal_lump", "technic:coal_dust 2"},
{"default:copper_lump", "technic:copper_dust 2"},
{"default:desert_stone", "default:desert_sand"},
{"default:gold_lump", "technic:gold_dust 2"},
{"default:iron_lump", "technic:wrought_iron_dust 2"},
{"default:tin_lump", "technic:tin_dust 2"},
{"technic:chromium_lump", "technic:chromium_dust 2"},
{"technic:uranium_lump", "technic:uranium_dust 2"},
{"technic:zinc_lump", "technic:zinc_dust 2"},
{"technic:lead_lump", "technic:lead_dust 2"},
{"technic:sulfur_lump", "technic:sulfur_dust 2"},
{"default:stone", "technic:stone_dust"},
{"default:sand", "technic:stone_dust"},
-- Other
{"default:cobble", "default:gravel"},
{"default:gravel", "default:dirt"},
{"default:stone", "default:sand"},
{"default:gravel", "default:sand"},
{"default:sandstone", "default:sand 2"}, -- reverse recipe can be found in the compressor
}
-- defuse the sandstone -> 4 sand recipe to avoid infinite sand bugs (also consult the inverse compressor recipe)
minetest.clear_craft({
recipe = {
{'default:sandstone'}
},
})
if minetest.get_modpath("farming") then
table.insert(recipes, {"farming:seed_wheat", "farming:flour 1"})
end
if minetest.get_modpath("moreores") then
table.insert(recipes, {"moreores:mithril_lump", "technic:mithril_dust 2"})
table.insert(recipes, {"moreores:silver_lump", "technic:silver_dust 2"})
end
if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
table.insert(recipes, {"gloopores:alatro_lump", "technic:alatro_dust 2"})
table.insert(recipes, {"gloopores:kalite_lump", "technic:kalite_dust 2"})
@ -43,13 +62,13 @@ for _, data in pairs(recipes) do
technic.register_grinder_recipe({input = {data[1]}, output = data[2]})
end
-- dusts
local function register_dust(name, ingot)
local lname = string.lower(name)
lname = string.gsub(lname, ' ', '_')
minetest.register_craftitem("technic:"..lname.."_dust", {
description = S("%s Dust"):format(S(name)),
inventory_image = "technic_"..lname.."_dust.png",
on_place_on_ground = minetest.craftitem_place_item,
})
if ingot then
minetest.register_craft({
@ -66,14 +85,18 @@ register_dust("Brass", "technic:brass_ingot")
register_dust("Bronze", "default:bronze_ingot")
register_dust("Carbon Steel", "technic:carbon_steel_ingot")
register_dust("Cast Iron", "technic:cast_iron_ingot")
register_dust("Chernobylite", "technic:chernobylite_block")
register_dust("Chromium", "technic:chromium_ingot")
register_dust("Coal", nil)
register_dust("Copper", "default:copper_ingot")
register_dust("Lead", "technic:lead_ingot")
register_dust("Gold", "default:gold_ingot")
register_dust("Mithril", "moreores:mithril_ingot")
register_dust("Silver", "moreores:silver_ingot")
register_dust("Stainless Steel", "technic:stainless_steel_ingot")
register_dust("Tin", "moreores:tin_ingot")
register_dust("Stone", "default:stone")
register_dust("Sulfur", nil)
register_dust("Tin", "default:tin_ingot")
register_dust("Wrought Iron", "technic:wrought_iron_ingot")
register_dust("Zinc", "technic:zinc_ingot")
if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
@ -84,9 +107,51 @@ if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
register_dust("Talinite", "glooptest:talinite_ingot")
end
for p = 0, 35 do
local nici = (p ~= 0 and p ~= 7 and p ~= 35) and 1 or nil
local psuffix = p == 7 and "" or p
local ingot = "technic:uranium"..psuffix.."_ingot"
local dust = "technic:uranium"..psuffix.."_dust"
minetest.register_craftitem(dust, {
description = S("%s Dust"):format(string.format(S("%.1f%%-Fissile Uranium"), p/10)),
inventory_image = "technic_uranium_dust.png",
on_place_on_ground = minetest.craftitem_place_item,
groups = {uranium_dust=1, not_in_creative_inventory=nici},
})
minetest.register_craft({
type = "cooking",
recipe = dust,
output = ingot,
})
technic.register_grinder_recipe({ input = {ingot}, output = dust })
end
local function uranium_dust(p)
return "technic:uranium"..(p == 7 and "" or p).."_dust"
end
for pa = 0, 34 do
for pb = pa+1, 35 do
local pc = (pa+pb)/2
if pc == math.floor(pc) then
minetest.register_craft({
type = "shapeless",
recipe = { uranium_dust(pa), uranium_dust(pb) },
output = uranium_dust(pc).." 2",
})
end
end
end
minetest.register_craft({
type = "fuel",
recipe = "technic:coal_dust",
burntime = 50,
})
if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
minetest.register_craft({
type = "fuel",
recipe = "technic:kalite_dust",
burntime = 37.5,
})
end

View File

@ -0,0 +1,62 @@
local S = technic.getter
local moretrees = minetest.get_modpath("moretrees")
local mesecons_materials = minetest.get_modpath("mesecons_materials")
local dye = minetest.get_modpath("dye")
-- sawdust, the finest wood/tree grinding
local sawdust = "technic:sawdust"
minetest.register_craftitem(sawdust, {
description = S("Sawdust"),
inventory_image = "technic_sawdust.png",
})
minetest.register_craft({ type = "fuel", recipe = sawdust, burntime = 6 })
technic.register_compressor_recipe({ input = {sawdust .. " 4"}, output = "default:wood" })
-- tree/wood grindings
local function register_tree_grinding(name, tree, wood, extract, grinding_color)
local lname = string.lower(name)
lname = string.gsub(lname, ' ', '_')
local grindings_name = "technic:"..lname.."_grindings"
local inventory_image = "technic_"..lname.."_grindings.png"
if grinding_color then
inventory_image = inventory_image .. "^[colorize:" .. grinding_color
end
minetest.register_craftitem(grindings_name, {
description = S("%s Grinding"):format(S(name)),
inventory_image = inventory_image,
})
minetest.register_craft({
type = "fuel",
recipe = grindings_name,
burntime = 8,
})
technic.register_grinder_recipe({ input = { tree }, output = grindings_name .. " 4" })
technic.register_grinder_recipe({ input = { grindings_name }, output = sawdust .. " 4" })
if wood then
technic.register_grinder_recipe({ input = { wood }, output = grindings_name })
end
if extract then
technic.register_extractor_recipe({ input = { grindings_name .. " 4" }, output = extract})
technic.register_separating_recipe({
input = { grindings_name .. " 4" },
output = { sawdust .. " 4", extract }
})
end
end
local rubber_tree_planks = moretrees and "moretrees:rubber_tree_planks"
local default_extract = dye and "dye:brown 2"
local grinding_recipes = {
{"Common Tree", "group:tree", "group:wood", default_extract },
{"Rubber Tree", "moretrees:rubber_tree_trunk", rubber_tree_planks, "technic:raw_latex"}
}
for _, data in pairs(grinding_recipes) do
register_tree_grinding(unpack(data))
end
if moretrees and dye then
-- https://en.wikipedia.org/wiki/Catechu ancient brown dye from the wood of acacia trees
register_tree_grinding("Acacia", "moretrees:acacia_trunk", "moretrees:acacia_planks", "dye:brown 8")
end

View File

@ -19,6 +19,10 @@ dofile(path.."/alloy_recipes.lua")
dofile(path.."/grinder_recipes.lua")
dofile(path.."/extractor_recipes.lua")
dofile(path.."/compressor_recipes.lua")
dofile(path.."/centrifuge_recipes.lua")
-- Multi-Machine Recipes
dofile(path.."/grindings.lua")
-- Machines
dofile(path.."/alloy_furnace.lua")
@ -26,4 +30,4 @@ dofile(path.."/electric_furnace.lua")
dofile(path.."/grinder.lua")
dofile(path.."/extractor.lua")
dofile(path.."/compressor.lua")
dofile(path.."/centrifuge.lua")

View File

@ -1,6 +1,9 @@
local S = technic.getter
local fs_helpers = pipeworks.fs_helpers
local tube_entry = "^pipeworks_tube_connection_metallic.png"
local tube = {
insert_object = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
@ -10,63 +13,175 @@ local tube = {
can_insert = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if meta:get_int("splitstacks") == 1 then
stack = stack:peek_item(1)
end
return inv:room_for_item("src", stack)
end,
connect_sides = {left = 1, right = 1, back = 1, top = 1, bottom = 1},
}
local connect_default = {"bottom", "back", "left", "right"}
local function round(v)
return math.floor(v + 0.5)
end
function technic.register_base_machine(data)
local typename = data.typename
local numitems = technic.recipes[typename].numitems
local input_size = technic.recipes[typename].input_size
local machine_name = data.machine_name
local machine_desc = data.machine_desc
local tier = data.tier
local ltier = string.lower(tier)
local groups = {cracky = 2}
local active_groups = {cracky = 2, not_in_creative_inventory = 1}
local groups = {cracky = 2, technic_machine = 1, ["technic_"..ltier] = 1}
if data.tube then
groups.tubedevice = 1
groups.tubedevice_receiver = 1
active_groups.tubedevice = 1
active_groups.tubedevice_receiver = 1
end
local active_groups = {not_in_creative_inventory = 1}
for k, v in pairs(groups) do active_groups[k] = v end
local formspec =
"invsize[8,9;]"..
"list[current_name;src;"..(4-numitems)..",1;"..numitems..",1;]"..
"size[8,9;]"..
"list[current_name;src;"..(4-input_size)..",1;"..input_size..",1;]"..
"list[current_name;dst;5,1;2,2;]"..
"list[current_player;main;0,5;8,4;]"..
"label[0,0;"..machine_desc:format(tier).."]"
"label[0,0;"..machine_desc:format(tier).."]"..
"listring[current_name;dst]"..
"listring[current_player;main]"..
"listring[current_name;src]"..
"listring[current_player;main]"
if data.upgrade then
formspec = formspec..
"list[current_name;upgrade1;1,3;1,1;]"..
"list[current_name;upgrade2;2,3;1,1;]"..
"label[1,4;"..S("Upgrade Slots").."]"
"label[1,4;"..S("Upgrade Slots").."]"..
"listring[current_name;upgrade1]"..
"listring[current_player;main]"..
"listring[current_name;upgrade2]"..
"listring[current_player;main]"
end
local run = function(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local eu_input = meta:get_int(tier.."_EU_input")
local machine_desc_tier = machine_desc:format(tier)
local machine_node = "technic:"..ltier.."_"..machine_name
local machine_demand = data.demand
-- Setup meta data if it does not exist.
if not eu_input then
meta:set_int(tier.."_EU_demand", machine_demand[1])
meta:set_int(tier.."_EU_input", 0)
return
end
local EU_upgrade, tube_upgrade = 0, 0
if data.upgrade then
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
end
if data.tube then
technic.handle_machine_pipeworks(pos, tube_upgrade)
end
local powered = eu_input >= machine_demand[EU_upgrade+1]
if powered then
meta:set_int("src_time", meta:get_int("src_time") + round(data.speed*10))
end
while true do
local result = technic.get_recipe(typename, inv:get_list("src"))
if not result then
technic.swap_node(pos, machine_node)
meta:set_string("infotext", S("%s Idle"):format(machine_desc_tier))
meta:set_int(tier.."_EU_demand", 0)
meta:set_int("src_time", 0)
return
end
meta:set_int(tier.."_EU_demand", machine_demand[EU_upgrade+1])
technic.swap_node(pos, machine_node.."_active")
meta:set_string("infotext", S("%s Active"):format(machine_desc_tier))
if meta:get_int("src_time") < round(result.time*10) then
if not powered then
technic.swap_node(pos, machine_node)
meta:set_string("infotext", S("%s Unpowered"):format(machine_desc_tier))
end
return
end
local output = result.output
if type(output) ~= "table" then output = { output } end
local output_stacks = {}
for _, o in ipairs(output) do
table.insert(output_stacks, ItemStack(o))
end
local room_for_output = true
inv:set_size("dst_tmp", inv:get_size("dst"))
inv:set_list("dst_tmp", inv:get_list("dst"))
for _, o in ipairs(output_stacks) do
if not inv:room_for_item("dst_tmp", o) then
room_for_output = false
break
end
inv:add_item("dst_tmp", o)
end
if not room_for_output then
technic.swap_node(pos, machine_node)
meta:set_string("infotext", S("%s Idle"):format(machine_desc_tier))
meta:set_int(tier.."_EU_demand", 0)
meta:set_int("src_time", round(result.time*10))
return
end
meta:set_int("src_time", meta:get_int("src_time") - round(result.time*10))
inv:set_list("src", result.new_input)
inv:set_list("dst", inv:get_list("dst_tmp"))
end
end
local tentry = tube_entry
if ltier == "lv" then
tentry = ""
end
minetest.register_node("technic:"..ltier.."_"..machine_name, {
description = machine_desc:format(tier),
tiles = {"technic_"..ltier.."_"..machine_name.."_top.png",
"technic_"..ltier.."_"..machine_name.."_bottom.png",
"technic_"..ltier.."_"..machine_name.."_side.png",
"technic_"..ltier.."_"..machine_name.."_side.png",
"technic_"..ltier.."_"..machine_name.."_side.png",
"technic_"..ltier.."_"..machine_name.."_front.png"},
tiles = {
"technic_"..ltier.."_"..machine_name.."_top.png"..tentry,
"technic_"..ltier.."_"..machine_name.."_bottom.png"..tentry,
"technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
"technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
"technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
"technic_"..ltier.."_"..machine_name.."_front.png"
},
paramtype2 = "facedir",
groups = groups,
tube = data.tube and tube or nil,
connect_sides = data.connect_sides or connect_default,
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
local form_buttons = ""
if not string.find(node.name, ":lv_") then
form_buttons = fs_helpers.cycling_button(
meta,
pipeworks.button_base,
"splitstacks",
{
pipeworks.button_off,
pipeworks.button_on
}
)..pipeworks.button_label
end
meta:set_string("infotext", machine_desc:format(tier))
meta:set_int("tube_time", 0)
meta:set_string("formspec", formspec)
meta:set_string("formspec", formspec..form_buttons)
local inv = meta:get_inventory()
inv:set_size("src", numitems)
inv:set_size("src", input_size)
inv:set_size("dst", 4)
inv:set_size("upgrade1", 1)
inv:set_size("upgrade2", 1)
@ -75,19 +190,44 @@ function technic.register_base_machine(data)
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
technic_run = run,
after_place_node = data.tube and pipeworks.after_place,
after_dig_node = technic.machine_after_dig_node,
on_receive_fields = function(pos, formname, fields, sender)
local node = minetest.get_node(pos)
if not pipeworks.may_configure(pos, sender) then return end
fs_helpers.on_receive_fields(pos, fields)
local meta = minetest.get_meta(pos)
local form_buttons = ""
if not string.find(node.name, ":lv_") then
form_buttons = fs_helpers.cycling_button(
meta,
pipeworks.button_base,
"splitstacks",
{
pipeworks.button_off,
pipeworks.button_on
}
)..pipeworks.button_label
end
meta:set_string("formspec", formspec..form_buttons)
end,
})
minetest.register_node("technic:"..ltier.."_"..machine_name.."_active",{
description = machine_desc:format(tier),
tiles = {"technic_"..ltier.."_"..machine_name.."_top.png",
"technic_"..ltier.."_"..machine_name.."_bottom.png",
"technic_"..ltier.."_"..machine_name.."_side.png",
"technic_"..ltier.."_"..machine_name.."_side.png",
"technic_"..ltier.."_"..machine_name.."_side.png",
"technic_"..ltier.."_"..machine_name.."_front_active.png"},
tiles = {
"technic_"..ltier.."_"..machine_name.."_top.png"..tentry,
"technic_"..ltier.."_"..machine_name.."_bottom.png"..tentry,
"technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
"technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
"technic_"..ltier.."_"..machine_name.."_side.png"..tentry,
"technic_"..ltier.."_"..machine_name.."_front_active.png"
},
paramtype2 = "facedir",
drop = "technic:"..ltier.."_"..machine_name,
groups = active_groups,
connect_sides = data.connect_sides or connect_default,
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
tube = data.tube and tube or nil,
@ -95,70 +235,27 @@ function technic.register_base_machine(data)
allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move,
})
minetest.register_abm({
nodenames = {"technic:"..ltier.."_"..machine_name,
"technic:"..ltier.."_"..machine_name.."_active"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local eu_input = meta:get_int(tier.."_EU_input")
local machine_desc_tier = machine_desc:format(tier)
local machine_node = "technic:"..ltier.."_"..machine_name
local machine_demand = data.demand
-- Setup meta data if it does not exist.
if not eu_input then
meta:set_int(tier.."_EU_demand", machine_demand[1])
meta:set_int(tier.."_EU_input", 0)
return
technic_run = run,
technic_disabled_machine_name = "technic:"..ltier.."_"..machine_name,
on_receive_fields = function(pos, formname, fields, sender)
local node = minetest.get_node(pos)
if not pipeworks.may_configure(pos, sender) then return end
fs_helpers.on_receive_fields(pos, fields)
local meta = minetest.get_meta(pos)
local form_buttons = ""
if not string.find(node.name, ":lv_") then
form_buttons = fs_helpers.cycling_button(
meta,
pipeworks.button_base,
"splitstacks",
{
pipeworks.button_off,
pipeworks.button_on
}
)..pipeworks.button_label
end
-- Power off automatically if no longer connected to a switching station
technic.switching_station_timeout_count(pos, tier)
local EU_upgrade, tube_upgrade = 0, 0
if data.upgrade then
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
end
if data.tube then
technic.handle_machine_pipeworks(pos, tube_upgrade)
end
local result = technic.get_recipe(typename, inv:get_list("src"))
if not result then
technic.swap_node(pos, machine_node)
meta:set_string("infotext", S("%s Idle"):format(machine_desc_tier))
meta:set_int(tier.."_EU_demand", 0)
return
end
if eu_input < machine_demand[EU_upgrade+1] then
-- Unpowered - go idle
technic.swap_node(pos, machine_node)
meta:set_string("infotext", S("%s Unpowered"):format(machine_desc_tier))
elseif eu_input >= machine_demand[EU_upgrade+1] then
-- Powered
technic.swap_node(pos, machine_node.."_active")
meta:set_string("infotext", S("%s Active"):format(machine_desc_tier))
meta:set_int("src_time", meta:get_int("src_time") + 1)
if meta:get_int("src_time") >= result.time / data.speed then
meta:set_int("src_time", 0)
local result_stack = ItemStack(result.output)
if inv:room_for_item("dst", result_stack) then
inv:set_list("src", result.new_input)
inv:add_item("dst", result_stack)
end
end
end
meta:set_int(tier.."_EU_demand", machine_demand[EU_upgrade+1])
end
meta:set_string("formspec", formspec..form_buttons)
end,
})
technic.register_machine(tier, "technic:"..ltier.."_"..machine_name, technic.receiver)

View File

@ -1,18 +1,24 @@
local have_ui = minetest.get_modpath("unified_inventory")
technic.recipes = {cooking = {numitems = 1}}
function technic.register_recipe_type(typename, desc, numitems)
numitems = numitems or 1
if unified_inventory and unified_inventory.register_craft_type then
technic.recipes = { cooking = { input_size = 1, output_size = 1 } }
function technic.register_recipe_type(typename, origdata)
local data = {}
for k, v in pairs(origdata) do data[k] = v end
data.input_size = data.input_size or 1
data.output_size = data.output_size or 1
if have_ui and unified_inventory.register_craft_type and data.output_size == 1 then
unified_inventory.register_craft_type(typename, {
description = desc,
height = numtiems,
width = 1,
description = data.description,
width = data.input_size,
height = 1,
})
end
technic.recipes[typename] = {numitems = numitems, recipes = {}}
data.recipes = {}
technic.recipes[typename] = data
end
local function get_recipe_index(items)
if not items or type(items) ~= "table" then return false end
local l = {}
for i, stack in ipairs(items) do
l[i] = ItemStack(stack):get_name()
@ -26,16 +32,26 @@ local function register_recipe(typename, data)
for i, stack in ipairs(data.input) do
data.input[i] = ItemStack(stack):to_string()
end
data.output = ItemStack(data.output):to_string()
if type(data.output) == "table" then
for i, v in ipairs(data.output) do
data.output[i] = ItemStack(data.output[i]):to_string()
end
else
data.output = ItemStack(data.output):to_string()
end
local recipe = {time = data.time, input = {}, output = data.output}
local index = get_recipe_index(data.input)
if not index then
print("[Technic] ignored registration of garbage recipe!")
return
end
for _, stack in ipairs(data.input) do
recipe.input[ItemStack(stack):get_name()] = ItemStack(stack):get_count()
end
technic.recipes[typename].recipes[index] = recipe
if unified_inventory then
if have_ui and technic.recipes[typename].output_size == 1 then
unified_inventory.register_craft({
type = typename,
output = data.output,
@ -65,12 +81,15 @@ function technic.get_recipe(typename, items)
end
end
local index = get_recipe_index(items)
if not index then
print("[Technic] ignored registration of garbage recipe!")
return
end
local recipe = technic.recipes[typename].recipes[index]
if recipe then
local new_input = {}
for i, stack in ipairs(items) do
if stack:get_count() < recipe.input[stack:get_name()] then
print(stack:get_name())
return nil
else
new_input[i] = ItemStack(stack)

View File

@ -5,11 +5,46 @@ function technic.register_solar_array(data)
local tier = data.tier
local ltier = string.lower(tier)
local run = function(pos, node)
-- The action here is to make the solar array produce power
-- Power is dependent on the light level and the height above ground
-- There are many ways to cheat by using other light sources like lamps.
-- As there is no way to determine if light is sunlight that is just a shame.
-- To take care of some of it solar panels do not work outside daylight hours or if
-- built below 0m
local pos1 = {}
local machine_name = S("Arrayed Solar %s Generator"):format(tier)
pos1.y = pos.y + 1
pos1.x = pos.x
pos1.z = pos.z
technic.get_or_load_node(pos1)
local light = minetest.get_node_light(pos1, nil)
local time_of_day = minetest.get_timeofday()
local meta = minetest.get_meta(pos)
light = light or 0
-- turn on array only during day time and if sufficient light
-- I know this is counter intuitive when cheating by using other light sources.
if light >= 12 and time_of_day >= 0.24 and time_of_day <= 0.76 and pos.y > 0 then
local charge_to_give = math.floor((light + pos.y) * data.power)
charge_to_give = math.max(charge_to_give, 0)
charge_to_give = math.min(charge_to_give, data.power * 50)
meta:set_string("infotext", S("@1 Active (@2)", machine_name,
technic.EU_string(charge_to_give)))
meta:set_int(tier.."_EU_supply", charge_to_give)
else
meta:set_string("infotext", S("%s Idle"):format(machine_name))
meta:set_int(tier.."_EU_supply", 0)
end
end
minetest.register_node("technic:solar_array_"..ltier, {
tiles = {"technic_"..ltier.."_solar_array_top.png", "technic_"..ltier.."_solar_array_bottom.png",
"technic_"..ltier.."_solar_array_side.png", "technic_"..ltier.."_solar_array_side.png",
"technic_"..ltier.."_solar_array_side.png", "technic_"..ltier.."_solar_array_side.png"},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1, ["technic_"..ltier]=1},
connect_sides = {"bottom"},
sounds = default.node_sound_wood_defaults(),
description = S("Arrayed Solar %s Generator"):format(tier),
active = false,
@ -24,45 +59,7 @@ function technic.register_solar_array(data)
local name = minetest.get_node(pos).name
meta:set_int(tier.."_EU_supply", 0)
end,
})
minetest.register_abm({
nodenames = {"technic:solar_array_"..ltier},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
-- The action here is to make the solar array produce power
-- Power is dependent on the light level and the height above ground
-- 130m and above is optimal as it would be above cloud level.
-- Height gives 1/4 of the effect, light 3/4. Max. effect is 2880EU for the array.
-- There are many ways to cheat by using other light sources like lamps.
-- As there is no way to determine if light is sunlight that is just a shame.
-- To take care of some of it solar panels do not work outside daylight hours or if
-- built below -10m
local pos1 = {}
local machine_name = S("Arrayed Solar %s Generator"):format(tier)
pos1.y = pos.y + 1
pos1.x = pos.x
pos1.z = pos.z
local light = minetest.get_node_light(pos1, nil)
local time_of_day = minetest.get_timeofday()
local meta = minetest.get_meta(pos)
light = light or 0
-- turn on array only during day time and if sufficient light
-- I know this is counter intuitive when cheating by using other light sources.
if light >= 12 and time_of_day >= 0.24 and time_of_day <= 0.76 and pos.y > 0 then
local charge_to_give = math.floor((light + pos.y) * data.power)
charge_to_give = math.max(charge_to_give, 0)
charge_to_give = math.min(charge_to_give, data.power * 50)
meta:set_string("infotext", S("%s Active"):format(machine_name).." ("..charge_to_give.."EU)")
meta:set_int(tier.."_EU_supply", charge_to_give)
else
meta:set_string("infotext", S("%s Idle"):format(machine_name))
meta:set_int(tier.."_EU_supply", 0)
end
end,
technic_run = run,
})
technic.register_machine(tier, "technic:solar_array_"..ltier, technic.producer)

View File

@ -7,74 +7,206 @@
-- Once the receiver side is powered it will deliver power to the other side.
-- Unused power is wasted just like any other producer!
local digilines_path = minetest.get_modpath("digilines")
local S = technic.getter
local cable_entry = "^technic_cable_connection_overlay.png"
local function set_supply_converter_formspec(meta)
local formspec = "size[5,2.25]"..
"field[0.3,0.5;2,1;power;"..S("Input Power")..";"..meta:get_int("power").."]"
if digilines_path then
formspec = formspec..
"field[2.3,0.5;3,1;channel;Digiline Channel;"..meta:get_string("channel").."]"
end
-- The names for these toggle buttons are explicit about which
-- state they'll switch to, so that multiple presses (arising
-- from the ambiguity between lag and a missed press) only make
-- the single change that the user expects.
if meta:get_int("mesecon_mode") == 0 then
formspec = formspec.."button[0,1;5,1;mesecon_mode_1;"..S("Ignoring Mesecon Signal").."]"
else
formspec = formspec.."button[0,1;5,1;mesecon_mode_0;"..S("Controlled by Mesecon Signal").."]"
end
if meta:get_int("enabled") == 0 then
formspec = formspec.."button[0,1.75;5,1;enable;"..S("%s Disabled"):format(S("Supply Converter")).."]"
else
formspec = formspec.."button[0,1.75;5,1;disable;"..S("%s Enabled"):format(S("Supply Converter")).."]"
end
meta:set_string("formspec", formspec)
end
local supply_converter_receive_fields = function(pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
local power = nil
if fields.power then
power = tonumber(fields.power) or 0
power = math.max(power, 0)
power = math.min(power, 10000)
power = 100 * math.floor(power / 100)
if power == meta:get_int("power") then power = nil end
end
if power then meta:set_int("power", power) end
if fields.channel then meta:set_string("channel", fields.channel) end
if fields.enable then meta:set_int("enabled", 1) end
if fields.disable then meta:set_int("enabled", 0) end
if fields.mesecon_mode_0 then meta:set_int("mesecon_mode", 0) end
if fields.mesecon_mode_1 then meta:set_int("mesecon_mode", 1) end
set_supply_converter_formspec(meta)
end
local mesecons = {
effector = {
action_on = function(pos, node)
minetest.get_meta(pos):set_int("mesecon_effect", 1)
end,
action_off = function(pos, node)
minetest.get_meta(pos):set_int("mesecon_effect", 0)
end
}
}
local digiline_def = {
receptor = {action = function() end},
effector = {
action = function(pos, node, channel, msg)
if type(msg) ~= "string" then
return
end
local meta = minetest.get_meta(pos)
if channel ~= meta:get_string("channel") then
return
end
msg = msg:lower()
if msg == "get" then
digilines.receptor_send(pos, digilines.rules.default, channel, {
enabled = meta:get_int("enabled"),
power = meta:get_int("power"),
mesecon_mode = meta:get_int("mesecon_mode")
})
return
elseif msg == "off" then
meta:set_int("enabled", 0)
elseif msg == "on" then
meta:set_int("enabled", 1)
elseif msg == "toggle" then
local onn = meta:get_int("enabled")
onn = 1-onn -- Mirror onn with pivot 0.5, so switch between 1 and 0.
meta:set_int("enabled", onn)
elseif msg:sub(1, 5) == "power" then
local power = tonumber(msg:sub(7))
if not power then
return
end
power = math.max(power, 0)
power = math.min(power, 10000)
power = 100 * math.floor(power / 100)
meta:set_int("power", power)
elseif msg:sub(1, 12) == "mesecon_mode" then
meta:set_int("mesecon_mode", tonumber(msg:sub(14)))
else
return
end
set_supply_converter_formspec(meta)
end
},
}
local run = function(pos, node, run_stage)
-- run only in producer stage.
if run_stage == technic.receiver then
return
end
local remain = 0.9
-- Machine information
local machine_name = S("Supply Converter")
local meta = minetest.get_meta(pos)
local enabled = meta:get_string("enabled")
if enabled == "" then
-- Backwards compatibility
minetest.registered_nodes["technic:supply_converter"].on_construct(pos)
enabled = true
else
enabled = enabled == "1"
end
enabled = enabled and (meta:get_int("mesecon_mode") == 0 or meta:get_int("mesecon_effect") ~= 0)
local demand = enabled and meta:get_int("power") or 0
local pos_up = {x=pos.x, y=pos.y+1, z=pos.z}
local pos_down = {x=pos.x, y=pos.y-1, z=pos.z}
local name_up = minetest.get_node(pos_up).name
local name_down = minetest.get_node(pos_down).name
local from = technic.get_cable_tier(name_up)
local to = technic.get_cable_tier(name_down)
if from and to then
local input = meta:get_int(from.."_EU_input")
meta:set_int(from.."_EU_demand", demand)
meta:set_int(from.."_EU_supply", 0)
meta:set_int(to.."_EU_demand", 0)
meta:set_int(to.."_EU_supply", input * remain)
meta:set_string("infotext", S("@1 (@2 @3 -> @4 @5)", machine_name,
technic.EU_string(input), from,
technic.EU_string(input * remain), to))
else
meta:set_string("infotext", S("%s Has Bad Cabling"):format(machine_name))
if to then
meta:set_int(to.."_EU_supply", 0)
end
if from then
meta:set_int(from.."_EU_demand", 0)
end
return
end
end
minetest.register_node("technic:supply_converter", {
description = S("Supply Converter"),
tiles = {"technic_supply_converter_top.png", "technic_supply_converter_bottom.png",
"technic_supply_converter_side.png", "technic_supply_converter_side.png",
"technic_supply_converter_side.png", "technic_supply_converter_side.png"},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2},
tiles = {
"technic_supply_converter_tb.png"..cable_entry,
"technic_supply_converter_tb.png"..cable_entry,
"technic_supply_converter_side.png",
"technic_supply_converter_side.png",
"technic_supply_converter_side.png",
"technic_supply_converter_side.png"
},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_all_tiers=1},
connect_sides = {"top", "bottom"},
sounds = default.node_sound_wood_defaults(),
drawtype = "nodebox",
paramtype = "light",
node_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
},
on_receive_fields = supply_converter_receive_fields,
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Supply Converter"))
meta:set_float("active", false)
if digilines_path then
meta:set_string("channel", "supply_converter"..minetest.pos_to_string(pos))
end
meta:set_int("power", 10000)
meta:set_int("enabled", 1)
meta:set_int("mesecon_mode", 0)
meta:set_int("mesecon_effect", 0)
set_supply_converter_formspec(meta)
end,
mesecons = mesecons,
digiline = digiline_def,
technic_run = run,
technic_on_disable = run,
})
minetest.register_craft({
output = 'technic:supply_converter 1',
recipe = {
{'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot'},
{'technic:mv_transformer', 'technic:mv_cable0', 'technic:lv_transformer'},
{'technic:mv_cable0', 'technic:rubber', 'technic:lv_cable0'},
{'technic:fine_gold_wire', 'technic:rubber', 'technic:doped_silicon_wafer'},
{'technic:mv_transformer', 'technic:machine_casing', 'technic:lv_transformer'},
{'technic:mv_cable', 'technic:rubber', 'technic:lv_cable'},
}
})
minetest.register_abm({
nodenames = {"technic:supply_converter"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local demand = 10000
local remain = 0.9
-- Machine information
local machine_name = S("Supply Converter")
local meta = minetest.get_meta(pos)
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 name_up = minetest.get_node(pos_up).name
local name_down = minetest.get_node(pos_down).name
local from = technic.get_cable_tier(name_up)
local to = technic.get_cable_tier(name_down)
if from and to then
technic.switching_station_timeout_count(pos, from)
local input = meta:get_int(from.."_EU_input")
meta:set_int(from.."_EU_demand", demand)
meta:set_int(from.."_EU_supply", 0)
meta:set_int(to.."_EU_demand", 0)
meta:set_int(to.."_EU_supply", input * remain)
meta:set_string("infotext", machine_name
.." ("..input.." "..from.." -> "
..input * remain.." "..to..")")
else
meta:set_string("infotext", S("%s Has Bad Cabling"):format(machine_name))
return
end
end,
})
for tier, machines in pairs(technic.machines) do
technic.register_machine(tier, "technic:supply_converter", technic.producer_receiver)
end

View File

@ -1,116 +1,147 @@
-- SWITCHING STATION
-- The switching station is the center of all power distribution on an electric network.
-- The station will collect all produced power from producers (PR) and batteries (BA)
-- and distribute it to receivers (RE) and depleted batteries (BA).
--
-- It works like this:
-- All PR,BA,RE nodes are indexed and tagged with the switching station.
-- The tagging is 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 all the power distribution logic resides in this single node.
--
-- Nodes connected to the network will have one or more of these parameters as meta 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
--
-- The reason the LV|MV|HV type is prepended toe meta data is because some machine could require several supplies to work.
-- This way the supplies are separated per network.
-- See also technic/doc/api.md
technic.networks = {}
technic.cables = {}
technic.redundant_warn = {}
local mesecons_path = minetest.get_modpath("mesecons")
local digilines_path = minetest.get_modpath("digilines")
local S = technic.getter
local cable_entry = "^technic_cable_connection_overlay.png"
minetest.register_craft({
output = "technic:switching_station",
recipe = {
{"technic:cast_iron_ingot", "technic:lv_transformer", "technic:cast_iron_ingot"},
{"default:copper_ingot", "technic:lv_cable0", "default:copper_ingot"},
{"technic:cast_iron_ingot", "technic:lv_cable0", "technic:cast_iron_ingot"}
{"", "technic:lv_transformer", ""},
{"default:copper_ingot", "technic:machine_casing", "default:copper_ingot"},
{"technic:lv_cable", "technic:lv_cable", "technic:lv_cable"}
}
})
local mesecon_def
if mesecons_path then
mesecon_def = {effector = {
rules = mesecon.rules.default,
}}
end
minetest.register_node("technic:switching_station",{
description = S("Switching Station"),
tiles = {"technic_water_mill_top_active.png", "technic_water_mill_top_active.png",
"technic_water_mill_top_active.png", "technic_water_mill_top_active.png",
"technic_water_mill_top_active.png", "technic_water_mill_top_active.png"},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2},
tiles = {
"technic_water_mill_top_active.png",
"technic_water_mill_top_active.png"..cable_entry,
"technic_water_mill_top_active.png",
"technic_water_mill_top_active.png",
"technic_water_mill_top_active.png",
"technic_water_mill_top_active.png"},
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_all_tiers=1},
connect_sides = {"bottom"},
sounds = default.node_sound_wood_defaults(),
drawtype = "nodebox",
paramtype = "light",
node_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Switching Station"))
meta:set_string("active", 1)
meta:set_string("channel", "switching_station"..minetest.pos_to_string(pos))
meta:set_string("formspec", "field[channel;Channel;${channel}]")
local poshash = minetest.hash_node_position(pos)
technic.redundant_warn.poshash = nil
end,
after_dig_node = function(pos)
minetest.forceload_free_block(pos)
pos.y = pos.y - 1
minetest.forceload_free_block(pos)
local poshash = minetest.hash_node_position(pos)
technic.redundant_warn.poshash = nil
end,
on_receive_fields = function(pos, formname, fields, sender)
if not fields.channel then
return
end
local plname = sender:get_player_name()
if minetest.is_protected(pos, plname) then
minetest.record_protection_violation(pos, plname)
return
end
local meta = minetest.get_meta(pos)
meta:set_string("channel", fields.channel)
end,
mesecons = mesecon_def,
digiline = {
receptor = {action = function() end},
effector = {
action = function(pos, node, channel, msg)
if msg ~= "GET" and msg ~= "get" then
return
end
local meta = minetest.get_meta(pos)
if channel ~= meta:get_string("channel") then
return
end
digilines.receptor_send(pos, digilines.rules.default, channel, {
supply = meta:get_int("supply"),
demand = meta:get_int("demand")
})
end
},
},
})
--------------------------------------------------
-- Functions to help the machines on the electrical network
--------------------------------------------------
-- This one provides a timeout for a node in case it was disconnected from the network
-- A node must be touched by the station continuously in order to function
function technic.switching_station_timeout_count(pos, tier)
local meta = minetest.get_meta(pos)
local timeout = meta:get_int(tier.."_EU_timeout")
if timeout == 0 then
meta:set_int(tier.."_EU_input", 0)
else
meta:set_int(tier.."_EU_timeout", timeout - 1)
end
end
--------------------------------------------------
-- Functions to traverse the electrical network
--------------------------------------------------
local function flatten(map)
local list = {}
for key, value in pairs(map) do
list[#list + 1] = value
end
return list
end
-- Add a wire node to the LV/MV/HV network
local add_new_cable_node = function(nodes, pos)
-- Ignore if the node has already been added
for i = 1, #nodes do
if pos.x == nodes[i].x and
pos.y == nodes[i].y and
pos.z == nodes[i].z then
return false
end
local function add_network_node(nodes, pos, network_id)
local node_id = minetest.hash_node_position(pos)
technic.cables[node_id] = network_id
if nodes[node_id] then
return false
end
table.insert(nodes, {x=pos.x, y=pos.y, z=pos.z, visited=1})
nodes[node_id] = pos
return true
end
local function add_cable_node(nodes, pos, network_id, queue)
if add_network_node(nodes, pos, network_id) then
queue[#queue + 1] = pos
end
end
-- Generic function to add found connected nodes to the right classification array
local check_node_subp = function(PR_nodes, RE_nodes, BA_nodes, all_nodes, pos, machines, tier)
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)
technic.get_or_load_node(pos)
local meta = minetest.get_meta(pos)
local name = minetest.get_node(pos).name
if technic.is_tier_cable(name, tier) then
add_new_cable_node(all_nodes, pos)
add_cable_node(all_nodes, pos,network_id, queue)
elseif machines[name] then
--dprint(name.." is a "..machines[name])
meta:set_string(tier.."_network",minetest.pos_to_string(sw_pos))
if machines[name] == technic.producer then
add_new_cable_node(PR_nodes, pos)
add_network_node(PR_nodes, pos, network_id)
elseif machines[name] == technic.receiver then
add_new_cable_node(RE_nodes, pos)
add_network_node(RE_nodes, pos, network_id)
elseif machines[name] == technic.producer_receiver then
add_new_cable_node(PR_nodes, pos)
add_new_cable_node(RE_nodes, pos)
add_network_node(PR_nodes, pos, network_id)
add_network_node(RE_nodes, pos, network_id)
elseif machines[name] == "SPECIAL" and
(pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) and
from_below then
-- Another switching station -> disable it
add_network_node(SP_nodes, pos, network_id)
meta:set_int("active", 0)
elseif machines[name] == technic.battery then
add_new_cable_node(BA_nodes, pos)
add_network_node(BA_nodes, pos, network_id)
end
meta:set_int(tier.."_EU_timeout", 2) -- Touch node
@ -118,8 +149,7 @@ local check_node_subp = function(PR_nodes, RE_nodes, BA_nodes, all_nodes, pos, m
end
-- Traverse a network given a list of machines and a cable type name
local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, all_nodes, i, machines, tier)
local pos = all_nodes[i]
local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, pos, machines, tier, sw_pos, network_id, queue)
local positions = {
{x=pos.x+1, y=pos.y, z=pos.z},
{x=pos.x-1, y=pos.y, z=pos.z},
@ -127,9 +157,8 @@ local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, all_nodes, i, ma
{x=pos.x, y=pos.y-1, z=pos.z},
{x=pos.x, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1}}
--print("ON")
for i, cur_pos in pairs(positions) do
check_node_subp(PR_nodes, RE_nodes, BA_nodes, all_nodes, cur_pos, machines, tier)
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
@ -140,36 +169,71 @@ local touch_nodes = function(list, tier)
end
end
local get_network = function(pos1, tier)
local cached = technic.networks[minetest.hash_node_position(pos1)]
local get_network = function(sw_pos, pos1, tier)
local network_id = minetest.hash_node_position(pos1)
local cached = technic.networks[network_id]
if cached and cached.tier == tier then
touch_nodes(cached.PR_nodes, tier)
touch_nodes(cached.BA_nodes, tier)
touch_nodes(cached.RE_nodes, tier)
for _, pos in ipairs(cached.SP_nodes) do
local meta = minetest.get_meta(pos)
meta:set_int("active", 0)
meta:set_string("active_pos", minetest.serialize(sw_pos))
end
return cached.PR_nodes, cached.BA_nodes, cached.RE_nodes
end
local i = 1
local PR_nodes = {}
local BA_nodes = {}
local RE_nodes = {}
local all_nodes = {pos1}
repeat
traverse_network(PR_nodes, RE_nodes, BA_nodes, all_nodes,
i, technic.machines[tier], tier)
i = i + 1
until all_nodes[i] == nil
technic.networks[minetest.hash_node_position(pos1)] = {tier = tier, PR_nodes = PR_nodes, RE_nodes = RE_nodes, BA_nodes = BA_nodes}
local SP_nodes = {}
local all_nodes = {}
local queue = {}
add_cable_node(all_nodes, pos1, network_id, queue)
while next(queue) do
local to_visit = {}
for _, pos in ipairs(queue) do
traverse_network(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes,
pos, technic.machines[tier], tier, sw_pos, network_id, to_visit)
end
queue = to_visit
end
PR_nodes = flatten(PR_nodes)
BA_nodes = flatten(BA_nodes)
RE_nodes = flatten(RE_nodes)
SP_nodes = flatten(SP_nodes)
all_nodes = flatten(all_nodes)
technic.networks[network_id] = {tier = tier, all_nodes = all_nodes, SP_nodes = SP_nodes,
PR_nodes = PR_nodes, RE_nodes = RE_nodes, BA_nodes = BA_nodes}
return PR_nodes, BA_nodes, RE_nodes
end
-----------------------------------------------
-- The action code for the switching station --
-----------------------------------------------
technic.powerctrl_state = true
minetest.register_chatcommand("powerctrl", {
params = "state",
description = "Enables or disables technic's switching station ABM",
privs = { basic_privs = true },
func = function(name, state)
if state == "on" then
technic.powerctrl_state = true
else
technic.powerctrl_state = false
end
end
})
minetest.register_abm({
nodenames = {"technic:switching_station"},
label = "Switching Station", -- allows the mtt profiler to profile this abm individually
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
if not technic.powerctrl_state then return end
local meta = minetest.get_meta(pos)
local meta1 = nil
local pos1 = {}
@ -187,25 +251,84 @@ minetest.register_abm({
-- Which kind of network are we on:
pos1 = {x=pos.x, y=pos.y-1, z=pos.z}
--Disable if necessary
if meta:get_int("active") ~= 1 then
minetest.forceload_free_block(pos)
minetest.forceload_free_block(pos1)
meta:set_string("infotext",S("%s Already Present"):format(machine_name))
local poshash = minetest.hash_node_position(pos)
if not technic.redundant_warn[poshash] then
technic.redundant_warn[poshash] = true
print("[TECHNIC] Warning: redundant switching station found near "..minetest.pos_to_string(pos))
end
return
end
local name = minetest.get_node(pos1).name
local tier = technic.get_cable_tier(name)
if tier then
PR_nodes, BA_nodes, RE_nodes = get_network(pos1, tier)
-- Forceload switching station
minetest.forceload_block(pos)
minetest.forceload_block(pos1)
PR_nodes, BA_nodes, RE_nodes = get_network(pos, pos1, tier)
else
--dprint("Not connected to a network")
meta:set_string("infotext", S("%s Has No Network"):format(machine_name))
minetest.forceload_free_block(pos)
minetest.forceload_free_block(pos1)
return
end
--dprint("nodes="..table.getn(all_nodes)
-- .." PR="..table.getn(PR_nodes)
-- .." BA="..table.getn(BA_nodes)
-- .." RE="..table.getn(RE_nodes))
-- Run all the nodes
local function run_nodes(list, run_stage)
for _, pos2 in ipairs(list) do
technic.get_or_load_node(pos2)
local node2 = minetest.get_node(pos2)
local nodedef
if node2 and node2.name then
nodedef = minetest.registered_nodes[node2.name]
end
if nodedef and nodedef.technic_run then
nodedef.technic_run(pos2, node2, run_stage)
end
end
end
run_nodes(PR_nodes, technic.producer)
run_nodes(RE_nodes, technic.receiver)
run_nodes(BA_nodes, technic.battery)
-- Strings for the meta data
local eu_demand_str = tier.."_EU_demand"
local eu_input_str = tier.."_EU_input"
local eu_supply_str = tier.."_EU_supply"
-- Distribute charge equally across multiple batteries.
local charge_total = 0
local battery_count = 0
for n, pos1 in pairs(BA_nodes) do
meta1 = minetest.get_meta(pos1)
local charge = meta1:get_int("internal_EU_charge")
if (meta1:get_int(eu_demand_str) ~= 0) then
charge_total = charge_total + charge
battery_count = battery_count + 1
end
end
local charge_distributed = math.floor(charge_total / battery_count)
for n, pos1 in pairs(BA_nodes) do
meta1 = minetest.get_meta(pos1)
if (meta1:get_int(eu_demand_str) ~= 0) then
meta1:set_int("internal_EU_charge", charge_distributed)
end
end
-- Get all the power from the PR nodes
local PR_eu_supply = 0 -- Total power
for _, pos1 in pairs(PR_nodes) do
@ -238,9 +361,26 @@ minetest.register_abm({
end
--dprint("Total BA demand:"..BA_eu_demand)
meta:set_string("infotext",
S("%s. Supply: %d Demand: %d"):format(
machine_name, PR_eu_supply, RE_eu_demand))
meta:set_string("infotext", S("@1. Supply: @2 Demand: @3",
machine_name, technic.EU_string(PR_eu_supply),
technic.EU_string(RE_eu_demand)))
-- If mesecon signal and power supply or demand changed then
-- send them via digilines.
if mesecons_path and digilines_path and mesecon.is_powered(pos) then
if PR_eu_supply ~= meta:get_int("supply") or
RE_eu_demand ~= meta:get_int("demand") then
local channel = meta:get_string("channel")
digilines.receptor_send(pos, digilines.rules.default, channel, {
supply = PR_eu_supply,
demand = RE_eu_demand
})
end
end
-- Data that will be used by the power monitor
meta:set_int("supply",PR_eu_supply)
meta:set_int("demand",RE_eu_demand)
-- If the PR supply is enough for the RE demand supply them all
if PR_eu_supply >= RE_eu_demand then
@ -303,6 +443,64 @@ minetest.register_abm({
meta1 = minetest.get_meta(pos1)
meta1:set_int(eu_input_str, 0)
end
end,
})
-- Timeout ABM
-- Timeout for a node in case it was disconnected from the network
-- A node must be touched by the station continuously in order to function
local function switching_station_timeout_count(pos, tier)
local meta = minetest.get_meta(pos)
local timeout = meta:get_int(tier.."_EU_timeout")
if timeout <= 0 then
meta:set_int(tier.."_EU_input", 0) -- Not needed anymore <-- actually, it is for supply converter
return true
else
meta:set_int(tier.."_EU_timeout", timeout - 1)
return false
end
end
minetest.register_abm({
label = "Machines: timeout check",
nodenames = {"group:technic_machine"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
for tier, machines in pairs(technic.machines) do
if machines[node.name] and switching_station_timeout_count(pos, tier) then
local nodedef = minetest.registered_nodes[node.name]
if nodedef and nodedef.technic_disabled_machine_name then
node.name = nodedef.technic_disabled_machine_name
minetest.swap_node(pos, node)
elseif nodedef and nodedef.technic_on_disable then
nodedef.technic_on_disable(pos, node)
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,
})
--Re-enable disabled switching station if necessary, similar to the timeout above
minetest.register_abm({
label = "Machines: re-enable check",
nodenames = {"technic:switching_station"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local pos1 = {x=pos.x,y=pos.y-1,z=pos.z}
local tier = technic.get_cable_tier(minetest.get_node(pos1).name)
if not tier then return end
if switching_station_timeout_count(pos, tier) then
local meta = minetest.get_meta(pos)
meta:set_int("active",1)
end
end,
})

View File

@ -0,0 +1,238 @@
# Blender v2.73 (sub 0) OBJ File: 'slope_test_cylinder_onetexture.blend'
# www.blender.org
o Cylinder_Cylinder.001
v 0.000000 -0.500000 -0.500000
v 0.000000 0.500000 -0.500000
v 0.097545 -0.500000 -0.490393
v 0.097545 0.500000 -0.490393
v 0.191342 -0.500000 -0.461940
v 0.191342 0.500000 -0.461940
v 0.277785 -0.500000 -0.415735
v 0.277785 0.500000 -0.415735
v 0.353553 -0.500000 -0.353554
v 0.353553 0.500000 -0.353554
v 0.415735 -0.500000 -0.277785
v 0.415735 0.500000 -0.277785
v 0.461940 -0.500000 -0.191342
v 0.461940 0.500000 -0.191342
v 0.490393 -0.500000 -0.097545
v 0.490393 0.500000 -0.097545
v 0.500000 -0.500000 -0.000000
v 0.500000 0.500000 -0.000000
v 0.490393 -0.500000 0.097545
v 0.490393 0.500000 0.097545
v 0.461940 -0.500000 0.191341
v 0.461940 0.500000 0.191341
v 0.415735 -0.500000 0.277785
v 0.415735 0.500000 0.277785
v 0.353553 -0.500000 0.353553
v 0.353553 0.500000 0.353553
v 0.277785 -0.500000 0.415735
v 0.277785 0.500000 0.415735
v 0.191342 -0.500000 0.461940
v 0.191342 0.500000 0.461940
v 0.097545 -0.500000 0.490392
v 0.097545 0.500000 0.490392
v -0.000000 -0.500000 0.500000
v -0.000000 0.500000 0.500000
v -0.097545 -0.500000 0.490392
v -0.097545 0.500000 0.490392
v -0.191342 -0.500000 0.461939
v -0.191342 0.500000 0.461939
v -0.277785 -0.500000 0.415734
v -0.277785 0.500000 0.415734
v -0.353554 -0.500000 0.353553
v -0.353554 0.500000 0.353553
v -0.415735 -0.500000 0.277785
v -0.415735 0.500000 0.277785
v -0.461940 -0.500000 0.191341
v -0.461940 0.500000 0.191341
v -0.490393 -0.500000 0.097545
v -0.490393 0.500000 0.097545
v -0.500000 -0.500000 -0.000001
v -0.500000 0.500000 -0.000001
v -0.490393 -0.500000 -0.097546
v -0.490393 0.500000 -0.097546
v -0.461940 -0.500000 -0.191342
v -0.461940 0.500000 -0.191342
v -0.415734 -0.500000 -0.277786
v -0.415734 0.500000 -0.277786
v -0.353553 -0.500000 -0.353554
v -0.353553 0.500000 -0.353554
v -0.277785 -0.500000 -0.415735
v -0.277785 0.500000 -0.415735
v -0.191341 -0.500000 -0.461940
v -0.191341 0.500000 -0.461940
v -0.097544 -0.500000 -0.490393
v -0.097544 0.500000 -0.490393
vt 0.499996 0.999997
vt 0.499995 0.000005
vt 0.562495 0.000004
vt 0.562496 0.999997
vt 0.624995 0.000003
vt 0.624997 0.999997
vt 0.687496 0.000002
vt 0.687497 0.999998
vt 0.749997 0.000001
vt 0.749997 0.999998
vt 0.812497 0.000001
vt 0.812497 0.999998
vt 0.874997 -0.000000
vt 0.874997 0.999998
vt 0.937498 -0.000000
vt 0.937498 0.999998
vt 0.999998 -0.000000
vt 0.999998 0.999998
vt 0.000005 0.999997
vt 0.000001 0.000024
vt 0.062500 0.000023
vt 0.062505 0.999996
vt 0.124999 0.000021
vt 0.125004 0.999996
vt 0.187498 0.000020
vt 0.187503 0.999995
vt 0.249997 0.000018
vt 0.250003 0.999994
vt 0.312497 0.000017
vt 0.312502 0.999994
vt 0.374997 0.000015
vt 0.375002 0.999993
vt 0.437496 0.000014
vt 0.437501 0.999993
vt 0.402487 0.009601
vt 0.597576 0.009614
vt 0.691371 0.038072
vt 0.777811 0.084282
vt 0.853576 0.146469
vt 0.915753 0.222242
vt 0.961953 0.308689
vt 0.990399 0.402487
vt 1.000000 0.500033
vt 0.990386 0.597577
vt 0.961928 0.691370
vt 0.915717 0.777811
vt 0.853531 0.853575
vt 0.777758 0.915753
vt 0.691312 0.961952
vt 0.597514 0.990398
vt 0.402424 0.990386
vt 0.308630 0.961928
vt 0.222188 0.915717
vt 0.146424 0.853531
vt 0.084248 0.777759
vt 0.038049 0.691313
vt 0.009602 0.597515
vt 0.000000 0.499970
vt 0.009614 0.402425
vt 0.038073 0.308630
vt 0.084283 0.222189
vt 0.146470 0.146424
vt 0.222243 0.084248
vt 0.308689 0.038048
vt 0.499927 0.999999
vt 0.084226 0.777725
vt 0.000000 0.499927
vt 0.222277 0.084224
vt 0.500074 0.000000
vt 0.915777 0.222279
vt 1.000000 0.500077
vt 0.777724 0.915775
vn 0.000000 -0.685700 -0.727900
vn 0.000000 0.685700 -0.727900
vn 0.142000 0.685700 -0.713900
vn 0.142000 -0.685700 -0.713900
vn 0.278500 0.685700 -0.672500
vn 0.278500 -0.685700 -0.672500
vn 0.404400 0.685700 -0.605200
vn 0.404400 -0.685700 -0.605200
vn 0.514700 0.685700 -0.514700
vn 0.514700 -0.685700 -0.514700
vn 0.605200 0.685700 -0.404400
vn 0.605200 -0.685700 -0.404400
vn 0.672500 0.685700 -0.278500
vn 0.672500 -0.685700 -0.278500
vn 0.713900 0.685700 -0.142000
vn 0.713900 -0.685700 -0.142000
vn 0.727900 0.685700 0.000000
vn 0.727900 -0.685700 0.000000
vn 0.713900 0.685700 0.142000
vn 0.713900 -0.685700 0.142000
vn 0.672500 0.685700 0.278500
vn 0.672500 -0.685700 0.278500
vn 0.605200 0.685700 0.404400
vn 0.605200 -0.685700 0.404400
vn 0.514700 0.685700 0.514700
vn 0.514700 -0.685700 0.514700
vn 0.404400 0.685700 0.605200
vn 0.404400 -0.685700 0.605200
vn 0.278500 0.685700 0.672500
vn 0.278500 -0.685700 0.672500
vn 0.142000 0.685700 0.713900
vn 0.142000 -0.685700 0.713900
vn 0.000000 0.685700 0.727900
vn 0.000000 -0.685700 0.727900
vn -0.142000 0.685700 0.713900
vn -0.142000 -0.685700 0.713900
vn -0.278500 0.685700 0.672500
vn -0.278500 -0.685700 0.672500
vn -0.404400 0.685700 0.605200
vn -0.404400 -0.685700 0.605200
vn -0.514700 0.685700 0.514700
vn -0.514700 -0.685700 0.514700
vn -0.605200 0.685700 0.404400
vn -0.605200 -0.685700 0.404400
vn -0.672500 0.685700 0.278500
vn -0.672500 -0.685700 0.278500
vn -0.713900 0.685700 0.142000
vn -0.713900 -0.685700 0.142000
vn -0.727900 0.685700 0.000000
vn -0.727900 -0.685700 0.000000
vn -0.713900 0.685700 -0.142000
vn -0.713900 -0.685700 -0.142000
vn -0.672500 0.685700 -0.278500
vn -0.672500 -0.685700 -0.278500
vn -0.605200 0.685700 -0.404400
vn -0.605200 -0.685700 -0.404400
vn -0.514700 0.685700 -0.514700
vn -0.514700 -0.685700 -0.514700
vn -0.404400 0.685700 -0.605200
vn -0.404400 -0.685700 -0.605200
vn -0.278500 0.685700 -0.672500
vn -0.278500 -0.685700 -0.672500
vn -0.142000 0.685700 -0.713900
vn -0.142000 -0.685700 -0.713900
s 1
f 1/1/1 2/2/2 4/3/3 3/4/4
f 3/4/4 4/3/3 6/5/5 5/6/6
f 5/6/6 6/5/5 8/7/7 7/8/8
f 7/8/8 8/7/7 10/9/9 9/10/10
f 9/10/10 10/9/9 12/11/11 11/12/12
f 11/12/12 12/11/11 14/13/13 13/14/14
f 13/14/14 14/13/13 16/15/15 15/16/16
f 15/16/16 16/15/15 18/17/17 17/18/18
f 17/19/18 18/20/17 20/21/19 19/22/20
f 19/22/20 20/21/19 22/23/21 21/24/22
f 21/24/22 22/23/21 24/25/23 23/26/24
f 23/26/24 24/25/23 26/27/25 25/28/26
f 25/28/26 26/27/25 28/29/27 27/30/28
f 27/30/28 28/29/27 30/31/29 29/32/30
f 29/32/30 30/31/29 32/33/31 31/34/32
f 31/34/32 32/33/31 34/2/33 33/1/34
f 33/1/34 34/2/33 36/3/35 35/4/36
f 35/4/36 36/3/35 38/5/37 37/6/38
f 37/6/38 38/5/37 40/7/39 39/8/40
f 39/8/40 40/7/39 42/9/41 41/10/42
f 41/10/42 42/9/41 44/11/43 43/12/44
f 43/12/44 44/11/43 46/13/45 45/14/46
f 45/14/46 46/13/45 48/15/47 47/16/48
f 47/16/48 48/15/47 50/17/49 49/18/50
f 49/19/50 50/20/49 52/21/51 51/22/52
f 51/22/52 52/21/51 54/23/53 53/24/54
f 53/24/54 54/23/53 56/25/55 55/26/56
f 55/26/56 56/25/55 58/27/57 57/28/58
f 57/28/58 58/27/57 60/29/59 59/30/60
f 59/30/60 60/29/59 62/31/61 61/32/62
f 4/35/3 2/2/2 64/36/63 62/37/61 60/38/59 58/39/57 56/40/55 54/41/53 52/42/51 50/43/49 48/44/47 46/45/45 44/46/43 42/47/41 40/48/39 38/49/37 36/50/35 34/1/33 32/51/31 30/52/29 28/53/27 26/54/25 24/55/23 22/56/21 20/57/19 18/58/17 16/59/15 14/60/13 12/61/11 10/62/9 8/63/7 6/64/5
f 63/34/64 64/33/63 2/2/2 1/1/1
f 61/32/62 62/31/61 64/33/63 63/34/64
f 1/65/1 3/51/4 5/52/6 7/53/8 9/54/10 11/66/12 13/56/14 15/57/16 17/67/18 19/59/20 21/60/22 23/61/24 25/62/26 27/68/28 29/64/30 31/35/32 33/69/34 35/36/36 37/37/38 39/38/40 41/39/42 43/70/44 45/41/46 47/42/48 49/71/50 51/44/52 53/45/54 55/46/56 57/47/58 59/72/60 61/49/62 63/50/64

View File

@ -0,0 +1,238 @@
# Blender v2.73 (sub 0) OBJ File: 'technic-cylinder-horizontal.blend'
# www.blender.org
o Cylinder_Cylinder.001
v 0.500000 0.000000 -0.500000
v -0.500000 0.000000 -0.500000
v 0.500000 0.097545 -0.490393
v -0.500000 0.097545 -0.490393
v 0.500000 0.191342 -0.461940
v -0.500000 0.191342 -0.461940
v 0.500000 0.277785 -0.415735
v -0.500000 0.277785 -0.415735
v 0.500000 0.353553 -0.353553
v -0.500000 0.353553 -0.353554
v 0.500000 0.415735 -0.277785
v -0.500000 0.415735 -0.277785
v 0.500000 0.461940 -0.191342
v -0.500000 0.461940 -0.191342
v 0.500000 0.490393 -0.097545
v -0.500000 0.490393 -0.097545
v 0.500000 0.500000 -0.000000
v -0.500000 0.500000 -0.000000
v 0.500000 0.490393 0.097545
v -0.500000 0.490393 0.097545
v 0.500000 0.461940 0.191342
v -0.500000 0.461940 0.191341
v 0.500000 0.415735 0.277785
v -0.500000 0.415735 0.277785
v 0.500000 0.353553 0.353553
v -0.500000 0.353553 0.353553
v 0.500000 0.277785 0.415735
v -0.500000 0.277785 0.415735
v 0.500000 0.191342 0.461940
v -0.500000 0.191342 0.461940
v 0.500000 0.097545 0.490393
v -0.500000 0.097545 0.490392
v 0.500000 -0.000000 0.500000
v -0.500000 -0.000000 0.500000
v 0.500000 -0.097546 0.490392
v -0.500000 -0.097545 0.490392
v 0.500000 -0.191342 0.461940
v -0.500000 -0.191342 0.461939
v 0.500000 -0.277785 0.415734
v -0.500000 -0.277785 0.415734
v 0.500000 -0.353554 0.353553
v -0.500000 -0.353554 0.353553
v 0.500000 -0.415735 0.277785
v -0.500000 -0.415735 0.277785
v 0.500000 -0.461940 0.191341
v -0.500000 -0.461940 0.191341
v 0.500000 -0.490393 0.097545
v -0.500000 -0.490393 0.097544
v 0.500000 -0.500000 -0.000001
v -0.500000 -0.500000 -0.000001
v 0.500000 -0.490393 -0.097546
v -0.500000 -0.490393 -0.097546
v 0.500000 -0.461940 -0.191342
v -0.500000 -0.461940 -0.191343
v 0.500000 -0.415734 -0.277786
v -0.500000 -0.415734 -0.277786
v 0.500000 -0.353553 -0.353554
v -0.500000 -0.353553 -0.353554
v 0.500000 -0.277785 -0.415735
v -0.500000 -0.277784 -0.415735
v 0.500000 -0.191341 -0.461940
v -0.500000 -0.191341 -0.461940
v 0.500000 -0.097544 -0.490393
v -0.500000 -0.097544 -0.490393
vt 0.000003 0.499996
vt 0.999995 0.499995
vt 0.999996 0.562495
vt 0.000002 0.562496
vt 0.999997 0.624995
vt 0.000003 0.624996
vt 0.999998 0.687496
vt 0.000002 0.687496
vt 0.999999 0.749997
vt 0.000002 0.749996
vt 0.999999 0.812497
vt 0.000002 0.812497
vt 1.000000 0.874997
vt 0.000001 0.874997
vt 1.000000 0.937498
vt 0.000001 0.937497
vt 1.000000 0.999998
vt 0.000001 0.999998
vt 0.000003 0.000005
vt 0.999976 0.000001
vt 0.999977 0.062500
vt 0.000003 0.062505
vt 0.999978 0.124999
vt 0.000004 0.125004
vt 0.999980 0.187498
vt 0.000005 0.187503
vt 0.999982 0.249997
vt 0.000005 0.250003
vt 0.999983 0.312497
vt 0.000006 0.312502
vt 0.999985 0.374997
vt 0.000007 0.375001
vt 0.999986 0.437496
vt 0.000007 0.437501
vt 0.009601 0.597512
vt 0.009614 0.402424
vt 0.038072 0.308628
vt 0.084283 0.222189
vt 0.146469 0.146424
vt 0.222242 0.084247
vt 0.308689 0.038047
vt 0.402487 0.009601
vt 0.500033 -0.000000
vt 0.597577 0.009613
vt 0.691371 0.038072
vt 0.777811 0.084283
vt 0.853575 0.146469
vt 0.915753 0.222242
vt 0.961952 0.308688
vt 0.990398 0.402486
vt 0.990386 0.597576
vt 0.961928 0.691370
vt 0.915717 0.777812
vt 0.853531 0.853576
vt 0.777759 0.915752
vt 0.691313 0.961951
vt 0.597515 0.990398
vt 0.499970 1.000000
vt 0.402425 0.990386
vt 0.308630 0.961927
vt 0.222189 0.915717
vt 0.146424 0.853530
vt 0.084248 0.777757
vt 0.038048 0.691311
vt 0.999999 0.500073
vt 0.777724 0.915774
vt 0.499927 0.999999
vt 0.084224 0.777723
vt 0.000000 0.499925
vt 0.222279 0.084223
vt 0.500078 -0.000000
vt 0.915775 0.222276
vn 0.685700 0.000000 -0.727900
vn -0.685700 0.000000 -0.727900
vn -0.685700 0.142000 -0.713900
vn 0.685700 0.142000 -0.713900
vn -0.685700 0.278500 -0.672500
vn 0.685700 0.278500 -0.672500
vn -0.685700 0.404400 -0.605200
vn 0.685700 0.404400 -0.605200
vn -0.685700 0.514700 -0.514700
vn 0.685700 0.514700 -0.514700
vn -0.685700 0.605200 -0.404400
vn 0.685700 0.605200 -0.404400
vn -0.685700 0.672500 -0.278500
vn 0.685700 0.672500 -0.278500
vn -0.685700 0.713900 -0.142000
vn 0.685700 0.713900 -0.142000
vn -0.685700 0.727900 0.000000
vn 0.685700 0.727900 0.000000
vn -0.685700 0.713900 0.142000
vn 0.685700 0.713900 0.142000
vn -0.685700 0.672500 0.278500
vn 0.685700 0.672500 0.278500
vn -0.685700 0.605200 0.404400
vn 0.685700 0.605200 0.404400
vn -0.685700 0.514700 0.514700
vn 0.685700 0.514700 0.514700
vn -0.685700 0.404400 0.605200
vn 0.685700 0.404400 0.605200
vn -0.685700 0.278500 0.672500
vn 0.685700 0.278500 0.672500
vn -0.685700 0.142000 0.713900
vn 0.685700 0.142000 0.713900
vn -0.685700 0.000000 0.727900
vn 0.685700 0.000000 0.727900
vn -0.685700 -0.142000 0.713900
vn 0.685700 -0.142000 0.713900
vn -0.685700 -0.278500 0.672500
vn 0.685700 -0.278500 0.672500
vn -0.685700 -0.404400 0.605200
vn 0.685700 -0.404400 0.605200
vn -0.685700 -0.514700 0.514700
vn 0.685700 -0.514700 0.514700
vn -0.685700 -0.605200 0.404400
vn 0.685700 -0.605200 0.404400
vn -0.685700 -0.672500 0.278500
vn 0.685700 -0.672500 0.278500
vn -0.685700 -0.713900 0.142000
vn 0.685700 -0.713900 0.142000
vn -0.685700 -0.727900 0.000000
vn 0.685700 -0.727900 0.000000
vn -0.685700 -0.713900 -0.142000
vn 0.685700 -0.713900 -0.142000
vn -0.685700 -0.672500 -0.278500
vn 0.685700 -0.672500 -0.278500
vn -0.685700 -0.605200 -0.404400
vn 0.685700 -0.605200 -0.404400
vn -0.685700 -0.514700 -0.514700
vn 0.685700 -0.514700 -0.514700
vn -0.685700 -0.404400 -0.605200
vn 0.685700 -0.404400 -0.605200
vn -0.685700 -0.278500 -0.672500
vn 0.685700 -0.278500 -0.672500
vn -0.685700 -0.142000 -0.713900
vn 0.685700 -0.142000 -0.713900
s 1
f 1/1/1 2/2/2 4/3/3 3/4/4
f 3/4/4 4/3/3 6/5/5 5/6/6
f 5/6/6 6/5/5 8/7/7 7/8/8
f 7/8/8 8/7/7 10/9/9 9/10/10
f 9/10/10 10/9/9 12/11/11 11/12/12
f 11/12/12 12/11/11 14/13/13 13/14/14
f 13/14/14 14/13/13 16/15/15 15/16/16
f 15/16/16 16/15/15 18/17/17 17/18/18
f 17/19/18 18/20/17 20/21/19 19/22/20
f 19/22/20 20/21/19 22/23/21 21/24/22
f 21/24/22 22/23/21 24/25/23 23/26/24
f 23/26/24 24/25/23 26/27/25 25/28/26
f 25/28/26 26/27/25 28/29/27 27/30/28
f 27/30/28 28/29/27 30/31/29 29/32/30
f 29/32/30 30/31/29 32/33/31 31/34/32
f 31/34/32 32/33/31 34/2/33 33/1/34
f 33/1/34 34/2/33 36/3/35 35/4/36
f 35/4/36 36/3/35 38/5/37 37/6/38
f 37/6/38 38/5/37 40/7/39 39/8/40
f 39/8/40 40/7/39 42/9/41 41/10/42
f 41/10/42 42/9/41 44/11/43 43/12/44
f 43/12/44 44/11/43 46/13/45 45/14/46
f 45/14/46 46/13/45 48/15/47 47/16/48
f 47/16/48 48/15/47 50/17/49 49/18/50
f 49/19/50 50/20/49 52/21/51 51/22/52
f 51/22/52 52/21/51 54/23/53 53/24/54
f 53/24/54 54/23/53 56/25/55 55/26/56
f 55/26/56 56/25/55 58/27/57 57/28/58
f 57/28/58 58/27/57 60/29/59 59/30/60
f 59/30/60 60/29/59 62/31/61 61/32/62
f 4/35/3 2/1/2 64/36/63 62/37/61 60/38/59 58/39/57 56/40/55 54/41/53 52/42/51 50/43/49 48/44/47 46/45/45 44/46/43 42/47/41 40/48/39 38/49/37 36/50/35 34/2/33 32/51/31 30/52/29 28/53/27 26/54/25 24/55/23 22/56/21 20/57/19 18/58/17 16/59/15 14/60/13 12/61/11 10/62/9 8/63/7 6/64/5
f 63/34/64 64/33/63 2/2/2 1/1/1
f 61/32/62 62/31/61 64/33/63 63/34/64
f 1/65/1 3/51/4 5/52/6 7/53/8 9/54/10 11/66/12 13/56/14 15/57/16 17/67/18 19/59/20 21/60/22 23/61/24 25/62/26 27/68/28 29/64/30 31/35/32 33/69/34 35/36/36 37/37/38 39/38/40 41/39/42 43/70/44 45/41/46 47/42/48 49/71/50 51/44/52 53/45/54 55/46/56 57/47/58 59/72/60 61/49/62 63/50/64

View File

@ -0,0 +1,33 @@
# Blender v2.73 (sub 0) OBJ File: 'technic-icorner.blend'
# www.blender.org
o Cube_Cube.000
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 -0.500000
v 0.500000 0.500000 0.500000
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v 0.500000 -0.500000 -0.500000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vn -0.000000 -0.000000 1.000000
vn -0.000000 -0.000000 -1.000000
vn 0.707100 0.707100 -0.000000
vn 1.000000 0.000000 -0.000000
vn 0.000000 -1.000000 -0.000000
vn -1.000000 -0.000000 -0.000000
vn 0.000000 0.707100 -0.707100
s off
f 6/1/1 1/2/1 7/3/1 8/4/1
f 2/1/2 5/3/2 3/4/2
f 2/1/3 1/2/3 5/4/3
f 6/2/4 8/3/4 9/4/4
f 9/1/5 8/2/5 7/3/5 3/4/5
f 3/3/6 7/4/6 1/1/6 2/2/6
f 1/1/7 6/2/7 9/3/7
l 1 4
l 3 4

View File

@ -0,0 +1,33 @@
# Blender v2.73 (sub 0) OBJ File: 'technic-icorner-upsdown.blend'
# www.blender.org
o Cube_Cube.000
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
v 0.500000 0.500000 -0.500000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vn -1.000000 0.000000 0.000000
vn 1.000000 -0.000000 0.000000
vn -0.000000 -0.707100 -0.707100
vn -0.000000 0.000000 -1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 -0.000000 1.000000
vn 0.707100 -0.707100 -0.000000
s off
f 6/1/1 1/2/1 7/3/1 8/4/1
f 2/1/2 5/3/2 3/4/2
f 2/1/3 1/2/3 5/4/3
f 6/2/4 8/3/4 9/4/4
f 9/1/5 8/2/5 7/3/5 3/4/5
f 3/3/6 7/4/6 1/1/6 2/2/6
f 1/1/7 6/2/7 9/3/7
l 1 4
l 3 4

View File

@ -0,0 +1,300 @@
# Blender v2.73 (sub 0) OBJ File: 'slope_test_blob_onetexture.blend'
# www.blender.org
o Cube
v 0.213679 -0.450000 -0.213679
v -0.213679 -0.450000 0.213680
v 0.213680 -0.450000 0.213680
v -0.213679 -0.450000 -0.213679
v 0.213679 0.450000 -0.213679
v -0.213679 0.450000 -0.213679
v 0.213679 0.450000 0.213680
v 0.500000 -0.000003 0.500000
v 0.277785 -0.415735 0.277785
v -0.277785 -0.415735 0.277785
v 0.353553 -0.353554 0.353553
v -0.353553 -0.353554 0.353553
v -0.500000 -0.000002 0.500000
v 0.415735 -0.277786 0.415735
v -0.277785 0.415735 0.277785
v 0.277785 0.415735 0.277785
v -0.415735 -0.277785 0.415735
v 0.353554 0.353553 0.353554
v -0.500000 -0.000002 -0.499983
v 0.461940 -0.191342 0.461940
v -0.461940 -0.191342 0.461940
v -0.353553 0.353553 0.353554
v 0.490393 -0.097546 0.490393
v 0.500000 -0.000002 -0.500000
v 0.490393 0.097545 -0.490392
v 0.490393 0.097545 0.490393
v -0.490393 -0.097546 0.490393
v 0.490393 -0.097545 -0.490393
v 0.461940 0.191341 0.461940
v -0.461940 0.191341 0.461940
v 0.461940 0.191342 -0.461940
v -0.490393 0.097545 0.490393
v 0.415735 0.277785 0.415735
v -0.490393 0.097545 -0.490392
v -0.415735 0.277785 0.415735
v 0.461940 -0.191341 -0.461940
v 0.415735 0.277785 -0.415735
v -0.461940 0.191341 -0.461940
v -0.415735 0.277785 -0.415735
v 0.415735 -0.277785 -0.415735
v -0.490393 -0.097546 -0.490392
v 0.353553 0.353553 -0.353553
v -0.213679 0.450000 0.213680
v -0.353553 0.353553 -0.353553
v 0.277785 0.415735 -0.277785
v -0.461940 -0.191342 -0.461939
v 0.353554 -0.353553 -0.353554
v -0.277785 0.415735 -0.277785
v -0.415735 -0.277785 -0.415734
v 0.277786 -0.415735 -0.277785
v -0.353553 -0.353554 -0.353553
v -0.277785 -0.415735 -0.277784
vt 0.038487 0.679029
vt 0.010047 0.589789
vt 0.990397 0.589790
vt 0.915772 0.767073
vt 0.084671 0.767071
vt 0.961957 0.679029
vt 0.852473 0.146294
vt 0.914576 0.232749
vt 0.084146 0.232744
vt 0.712776 0.000003
vt 0.221926 0.061588
vt 0.285951 0.000000
vt 0.285945 0.999818
vt 0.221920 0.938229
vt 0.712771 0.999818
vt 0.009578 0.589789
vt 0.989138 0.589792
vt 0.960721 0.679031
vt 0.286638 0.000000
vt 0.777884 0.061589
vt 0.222561 0.061589
vt 0.777608 0.938229
vt 0.222164 0.938229
vt 0.146413 0.853527
vt 0.286255 0.999818
vt 0.713517 0.999818
vt 0.776800 0.061592
vt 0.146251 0.146290
vt 0.000000 0.499907
vt 0.989139 0.410032
vt 0.998734 0.499910
vt 0.853618 0.146291
vt 0.915772 0.232746
vt 0.146826 0.146290
vt 0.961957 0.320789
vt 0.084672 0.232745
vt 0.990397 0.410029
vt 0.038487 0.320789
vt 0.776796 0.938230
vt 0.777790 0.938229
vt 0.146467 0.853526
vt 0.853556 0.853527
vt 0.146825 0.853526
vt 1.000000 0.499907
vt 0.010047 0.410028
vt 0.146246 0.853527
vt 0.222559 0.938228
vt 0.777882 0.938230
vt 0.915737 0.767073
vt 0.084287 0.767072
vt 0.038083 0.679029
vt 0.961941 0.679029
vt 0.037995 0.679029
vt 0.960723 0.320792
vt 0.037998 0.320787
vt 0.009580 0.410028
vt 0.990167 0.589790
vt 0.999772 0.499909
vt 0.961721 0.679029
vt 0.084246 0.767072
vt 0.915526 0.767072
vt 0.853359 0.853527
vt 0.914573 0.767074
vt 0.084142 0.767072
vt 0.852470 0.853528
vt 0.777609 0.061590
vt 0.853360 0.146293
vt 0.222166 0.061589
vt 0.146414 0.146291
vt 0.915527 0.232748
vt 0.084247 0.232746
vt 0.961721 0.320791
vt 0.038052 0.320789
vt 0.990167 0.410031
vt 0.713686 0.999818
vt 0.749950 0.250050
vt 0.749950 0.749950
vt 0.250050 0.749950
vt 0.250050 0.250050
vt 0.713807 0.000000
vt 0.286258 0.000000
vt 0.713519 0.000001
vt 0.250050 0.250050
vt 0.749950 0.250050
vt 0.749950 0.749950
vt 0.286636 0.999817
vt 0.777791 0.061589
vt 0.146467 0.146291
vt 0.084287 0.232745
vt 0.915737 0.232746
vt 0.961941 0.320789
vt 0.000444 0.499907
vt 0.713687 0.000000
vt 0.713805 0.999818
vn -0.620400 0.479600 0.620400
vn -0.683900 0.254100 0.683900
vn 0.683900 0.254100 0.683900
vn 0.531000 0.660300 0.531000
vn -0.531000 0.660300 0.531000
vn 0.620400 0.479600 0.620400
vn -0.429700 -0.794100 0.429700
vn -0.531000 -0.660300 0.531000
vn -0.531000 -0.660300 -0.531000
vn -0.185700 -0.964900 0.185700
vn -0.325800 -0.887500 -0.325800
vn -0.185700 -0.964900 -0.185700
vn -0.185700 0.964900 -0.185700
vn -0.325800 0.887500 -0.325800
vn -0.185700 0.964900 0.185700
vn -0.683900 0.254000 -0.683900
vn 0.325800 -0.887500 0.325800
vn -0.325800 -0.887500 0.325800
vn 0.325800 0.887500 -0.325800
vn 0.429700 0.794100 -0.429700
vn 0.185700 0.964900 -0.185700
vn -0.429700 -0.794100 -0.429700
vn -0.707100 0.000000 -0.707100
vn -0.683900 -0.254100 0.683900
vn -0.707100 0.000000 0.707100
vn 0.429700 -0.794100 0.429700
vn 0.531000 -0.660300 0.531000
vn 0.620400 -0.479600 0.620400
vn 0.683900 -0.254100 0.683900
vn -0.620400 -0.479600 0.620400
vn -0.325800 0.887500 0.325800
vn 0.185700 0.964900 0.185700
vn 0.325800 0.887500 0.325800
vn 0.429700 0.794100 0.429700
vn -0.429700 0.794100 0.429700
vn 0.707100 0.000000 0.707100
vn -0.429700 0.794100 -0.429700
vn 0.531000 0.660300 -0.531000
vn 0.683900 0.254100 -0.683900
vn 0.707100 0.000000 -0.707100
vn 0.620400 0.479600 -0.620400
vn -0.620400 0.479600 -0.620400
vn -0.620400 -0.479600 -0.620400
vn -0.683900 -0.254000 -0.683900
vn 0.683900 -0.254100 -0.683900
vn -0.531000 0.660300 -0.531000
vn 0.325800 -0.887500 -0.325800
vn 0.429700 -0.794100 -0.429700
vn 0.531000 -0.660300 -0.531000
vn 0.620400 -0.479600 -0.620400
vn 0.185700 -0.964900 -0.185700
vn 0.185700 -0.964900 0.185700
s 1
f 30/1/1 32/2/2 26/3/3
f 33/4/4 35/5/5 29/6/6
f 12/7/7 17/8/8 49/9/9
f 2/10/10 52/11/11 4/12/12
f 6/13/13 48/14/14 43/15/15
f 34/16/16 32/17/2 30/18/1
f 2/19/10 9/20/17 10/21/18
f 48/22/14 45/23/19 42/24/20
f 5/25/21 45/23/19 6/26/13
f 10/27/18 12/7/7 51/28/22
f 19/29/23 27/30/24 13/31/25
f 9/20/17 11/32/26 10/21/18
f 11/32/26 14/33/27 12/34/7
f 14/33/27 20/35/28 17/36/8
f 20/35/28 23/37/29 21/38/30
f 43/15/15 48/14/14 15/39/31
f 7/25/32 16/23/33 45/40/19
f 18/41/34 42/42/20 45/40/19
f 29/6/6 30/1/1 26/3/3
f 22/43/35 33/4/4 18/42/34
f 26/3/3 32/2/2 8/44/36
f 8/44/36 27/45/24 23/37/29
f 11/32/26 12/34/7 10/21/18
f 14/33/27 17/36/8 12/34/7
f 20/35/28 21/38/30 17/36/8
f 23/37/29 27/45/24 21/38/30
f 10/27/18 52/11/11 2/10/10
f 15/39/31 48/14/14 44/46/37
f 22/43/35 35/5/5 33/4/4
f 15/47/31 22/43/35 16/48/33
f 37/49/38 42/42/20 18/41/34
f 33/50/4 29/51/6 37/49/38
f 8/29/36 25/3/39 26/16/3
f 24/44/40 25/3/39 8/29/36
f 29/51/6 26/16/3 31/52/41
f 26/16/3 25/3/39 31/52/41
f 29/51/6 31/52/41 37/49/38
f 38/53/42 34/16/16 30/18/1
f 19/29/23 32/17/2 34/16/16
f 13/31/25 32/17/2 19/29/23
f 17/8/8 21/54/30 46/55/43
f 21/54/30 27/30/24 41/56/44
f 8/29/36 28/37/45 24/44/40
f 34/57/16 25/16/39 19/58/23
f 38/59/42 31/51/41 34/57/16
f 31/51/41 25/16/39 34/57/16
f 37/60/38 38/59/42 39/61/46
f 37/60/38 31/51/41 38/59/42
f 44/62/37 42/24/20 37/60/38
f 38/53/42 30/18/1 35/63/5
f 39/64/46 35/63/5 22/65/35
f 52/66/11 51/67/22 50/68/47
f 51/67/22 47/69/48 50/68/47
f 51/67/22 49/70/9 47/69/48
f 49/70/9 40/71/49 47/69/48
f 49/70/9 46/72/43 40/71/49
f 46/72/43 36/73/50 40/71/49
f 19/58/23 28/56/45 41/74/44
f 46/72/43 41/74/44 36/73/50
f 41/74/44 28/56/45 36/73/50
f 22/43/35 18/42/34 16/48/33
f 5/75/21 7/25/32 45/40/19
f 2/76/10 4/77/12 1/78/51 3/79/52
f 44/62/37 48/22/14 42/24/20
f 35/5/5 30/1/1 29/6/6
f 3/80/52 9/20/17 2/19/10
f 45/23/19 48/22/14 6/26/13
f 1/81/51 52/66/11 50/68/47
f 39/61/46 44/62/37 37/60/38
f 52/66/11 1/81/51 4/82/12
f 24/29/40 28/56/45 19/58/23
f 7/78/32 5/83/21 6/84/13 43/85/15
f 24/29/40 19/58/23 25/16/39
f 15/47/31 16/48/33 43/86/15
f 22/65/35 44/46/37 39/64/46
f 39/64/46 38/53/42 35/63/5
f 41/56/44 27/30/24 19/29/23
f 46/55/43 21/54/30 41/56/44
f 49/9/9 17/8/8 46/55/43
f 51/28/22 12/7/7 49/9/9
f 52/11/11 10/27/18 51/28/22
f 9/68/17 50/87/47 11/88/26
f 50/87/47 47/32/48 11/88/26
f 11/88/26 47/32/48 14/89/27
f 47/32/48 40/90/49 14/89/27
f 14/89/27 40/90/49 20/73/28
f 40/90/49 36/91/50 20/73/28
f 23/56/29 28/37/45 8/29/36
f 20/73/28 36/91/50 23/56/29
f 36/91/50 28/37/45 23/56/29
f 13/92/25 8/44/36 32/2/2
f 50/87/47 9/68/17 1/93/51
f 13/92/25 27/45/24 8/44/36
f 16/23/33 18/41/34 45/40/19
f 22/65/35 15/39/31 44/46/37
f 9/68/17 3/81/52 1/93/51
f 33/50/4 37/49/38 18/41/34
f 43/86/15 16/48/33 7/94/32

View File

@ -0,0 +1,132 @@
# Blender v2.73 (sub 0) OBJ File: 'slope_test_quarter_round_onetexture.blend'
# www.blender.org
o Cylinder
v -0.500000 0.490393 -0.097545
v 0.500000 0.490393 -0.097545
v -0.500000 0.461940 -0.191342
v 0.500000 0.461940 -0.191342
v -0.500000 0.415735 -0.277785
v 0.500000 0.415735 -0.277785
v -0.500000 0.353553 -0.353553
v 0.500000 0.353553 -0.353553
v -0.500000 0.277785 -0.415735
v 0.500000 0.277785 -0.415735
v -0.500000 0.191342 -0.461940
v 0.500000 0.191342 -0.461940
v -0.500000 0.097545 -0.490393
v 0.500000 0.097545 -0.490393
v 0.500000 -0.000000 -0.500000
v 0.500000 0.490393 -0.097545
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.000000 -0.500000
v -0.500000 0.500000 -0.000000
v 0.500000 0.500000 0.000000
v -0.500000 0.490393 -0.097545
v -0.500000 0.461940 -0.191342
v -0.500000 0.415735 -0.277785
v -0.500000 0.353553 -0.353553
v -0.500000 0.277785 -0.415735
v -0.500000 0.191342 -0.461940
v -0.500000 0.097545 -0.490393
v -0.500000 0.000000 0.000000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v -0.500000 0.500000 0.500000
v -0.500000 0.000000 -0.500000
v -0.500000 0.500000 -0.000000
v 0.500000 0.461940 -0.191342
v 0.500000 0.415735 -0.277785
v 0.500000 0.353553 -0.353553
v 0.500000 0.277785 -0.415735
v 0.500000 0.191342 -0.461940
v 0.500000 0.097545 -0.490393
v 0.500000 -0.000000 -0.500000
v 0.500000 -0.000000 -0.000000
v 0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 0.500000
v 0.500000 0.500000 0.500000
v 0.500000 0.500000 0.000000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 0.500000
vt 1.000000 0.000000
vt 1.000000 0.500000
vt 0.500001 0.500000
vt 0.500001 1.000000
vt 0.000003 1.000000
vt 0.000003 0.000000
vt 0.597546 0.990393
vt 0.691342 0.961940
vt 1.000000 1.000000
vt 0.990393 0.597545
vt 0.961940 0.691341
vt 0.777786 0.915735
vt 0.853554 0.853553
vt 0.915735 0.777785
vt 0.146446 0.853552
vt 0.084265 0.777783
vt 0.038060 0.691340
vt 0.308658 0.961938
vt 0.222214 0.915733
vt 0.000000 0.499999
vt 0.402454 0.990391
vt 0.009607 0.597544
vt 1.000000 0.375000
vt 0.000000 0.375000
vt 0.000000 0.250000
vt 1.000000 0.250000
vt 0.000000 0.125000
vt 1.000000 0.125000
vt 0.000000 0.875000
vt 1.000000 0.875000
vt 0.000000 0.750000
vt 1.000000 0.750000
vt 0.000000 0.625000
vt 1.000000 0.625000
vn 1.000000 -0.000000 0.000000
vn -0.000000 0.000000 1.000000
vn -0.000000 -1.000000 0.000000
vn -1.000000 0.000000 0.000000
vn 0.000000 0.980800 -0.195100
vn 0.000000 0.923900 -0.382700
vn -0.000000 0.831500 -0.555600
vn -0.000000 0.707100 -0.707100
vn -0.000000 0.555600 -0.831500
vn -0.000000 0.382700 -0.923900
vn -0.000000 0.195100 -0.980800
vn 0.000000 1.000000 -0.000000
vn 0.000000 0.998800 -0.049100
vn -0.000000 0.049100 -0.998800
vn -0.000000 0.000000 -1.000000
s off
f 46/1/1 44/2/1 45/3/1 49/4/1 48/5/1 47/6/1
f 16/7/1 49/4/1 45/3/1 38/8/1
f 55/5/2 53/6/2 54/1/2 56/9/2
f 43/10/1 42/11/1 45/3/1 44/2/1
f 39/12/1 38/8/1 45/3/1 40/13/1
f 41/14/1 40/13/1 45/3/1 42/11/1
f 50/9/3 51/5/3 52/6/3 17/1/3
f 28/15/4 29/16/4 30/17/4 32/3/4
f 26/18/4 27/19/4 28/15/4 32/3/4
f 35/9/4 37/4/4 32/3/4 36/20/4 34/6/4 33/1/4
f 37/4/4 25/21/4 26/18/4 32/3/4
f 30/17/4 31/22/4 36/20/4 32/3/4
s 1
f 1/23/5 2/24/5 4/25/6 3/26/6
f 3/26/6 4/25/6 6/27/7 5/28/7
f 5/28/7 6/27/7 8/6/8 7/1/8
f 7/9/8 8/5/8 10/29/9 9/30/9
f 9/30/9 10/29/9 12/31/10 11/32/10
f 11/32/10 12/31/10 14/33/11 13/34/11
f 21/5/12 24/20/13 23/2/13 20/9/12
f 13/34/11 14/33/11 15/20/14 22/2/14
f 23/2/13 24/20/13 2/24/5 1/23/5
f 18/1/15 22/2/14 15/20/14 19/6/15

View File

@ -0,0 +1,23 @@
# Blender v2.73 (sub 0) OBJ File: 'technic-ocorner.blend'
# www.blender.org
o Cube_Cube.002
v -0.500000 0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 0.500000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vn 0.000000 -1.000000 -0.000000
vn 0.000000 0.000000 1.000000
vn -1.000000 -0.000000 0.000000
vn -0.000000 0.707100 -0.707100
vn 0.707100 0.707100 -0.000000
s off
f 3/1/1 2/2/1 4/3/1 5/4/1
f 1/2/2 3/3/2 5/4/2
f 1/1/3 2/3/3 3/4/3
f 1/1/4 4/3/4 2/4/4
f 1/2/5 5/3/5 4/4/5

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