1
0
mirror of https://github.com/HybridDog/nether-pack.git synced 2025-06-29 22:51:05 +02:00

84 Commits
test ... master

Author SHA1 Message Date
8be1f839c5 Move most of mapgen into mapgen thread 2024-04-03 17:16:20 +02:00
9c3fc65544 Also move out the grow_structure functions 2024-04-03 17:16:20 +02:00
0351e12bac Move mapgen code out of init.lua 2024-04-03 17:16:20 +02:00
1c033a048f Helper functions for other mods and an obsidian portal bugfix (#15)
* The obsidian portal is the first way for a player to reach the nether,
  so if damage is enabled and `nether.trap_players` is disabled,
  the obsidian portal should teleport the player instead of killing him/her
  since after death he/she respawns in the overworld and not in the nether.
  A small change in `obsi_teleport_player` fixes this problem.
  Fixes #16.
* There exist other mods which need to check if players are in the nether and
  teleport them to/from the nether, so we add four helper functions:
  `nether.is_player_in_nether`, `nether.is_player_trapped_in_nether`.
  `nether.external_nether_teleport` and `nether.registry_update`.
  Fixes #14.
* Add the `in_hell`, `trapped_in_hell` and `update_hells_registry` chat
  commands, which can be used for debugging
* `players_in_nether` has no meaningful effect if `nether.trap_players` is
  disabled, so we rename it to `players_trapped_in_nether`.
* Add `nether.bottom`, which approximately corresponds to the lower end of the
  nether
2024-02-29 21:05:03 +01:00
02d14a8970 Fix nether portal detection
The function which calculates positions of an empty square currently has a bug:
it returns the northeastern and southwestern corners twice
and omits the northwestern and southeastern ones.
This leads to a nether portal detection which is not rigorous enough, skipping eight nodes.

This commit fixes the problem.
Closes #13
2023-10-30 17:39:56 +01:00
76708b02d5 Update the Readme 2022-08-20 20:19:58 +02:00
f12d33c743 Replace deprecated function names (e.g. moveto -> move_to) and make stairs optional 2022-08-20 20:11:35 +02:00
435cef6f81 Remove the unused vector_extras dependency 2022-08-20 19:20:13 +02:00
01cd7c8e5b New nether guide
* Remove code which uses the font size setting to position text and images. Instead use Minetest's hypertext formspec element
* Rewrite many parts of the guide contents, e.g. "you" -> "we", more detailed portal description
* Add a setting to permit viewing it in the overworld (enabled by default)
* Update the Readme

I have set the font size to 24, which works well for me on a 1920x1080 screen with somewhat high DPI. The text written in hypertext apparently ignores the Minetest font size setting, so it may look bad on different screens.
2022-08-19 18:14:44 +02:00
817efcdd29 Add settingtypes.txt to configure player trapping and message logging
There are also some changes to fix problems when trapping is enabled while damage is disabled or the other way round.
2022-08-16 17:25:41 +02:00
6507e43dc5 Do not ignore the portal code if damage is enabled and the "nether_players" file does not exist
I have accidentally introduced the bug in commit 4a7dd247e7.
It was discovered thanks to the people who reported it on the Minetest forum.
2022-08-15 15:47:16 +02:00
27bf94c4d0 Fix portal player y pos being off by 1 node sometimes 2022-07-26 17:52:25 +02:00
27be1dd740 Mention the problematic guide in the Readme 2021-12-22 19:07:12 +01:00
c35d18a519 Fix some deprecation warnings 2021-12-22 18:46:56 +01:00
fb1eca6c11 Add .luacheckrc and do some code fixes 2021-12-22 18:46:52 +01:00
be64a982f8 Remove the invisible folder 2021-12-22 17:53:32 +01:00
56f5909e0f Relicense; WTFPL allows it 2021-12-22 17:45:59 +01:00
7cdd0471a2 depends.txt -> mod.conf 2021-12-22 17:44:27 +01:00
b876d8f2b9 Move the mod description to the forum to reduce duplicate text 2021-12-22 17:39:40 +01:00
870b6a9d47 Fix nether leaves visual_scale
Also, update README
2019-03-10 12:35:51 +01:00
0d4a302103 fix creative dig 2018-09-10 00:10:11 +02:00
fadf202663 Fix object teleportation from and to nether 2018-08-18 20:00:40 +02:00
df2d49edb0 Override player:set_pos etc. to disallow teleports from/to nether
constantly testing the player position is not longer necessary.
2018-08-15 19:52:39 +02:00
4a7dd247e7 Do not use players_in_nether as list but hashmap
Also, comment broken function
2018-08-15 17:31:15 +02:00
2f3522598c portal.lua: Fix some 80 char line breaks 2018-08-15 16:57:23 +02:00
020ab700ff Fix get_node vs get_node_or_nil usage 2018-08-15 16:52:04 +02:00
5925dc5606 mapgen: Use buffers for memory usage optimisation 2018-03-18 18:39:44 +01:00
6e2ffa04ea guide: fix portal indrigents 2017-12-31 22:02:22 +01:00
8a3d0b0634 Update debug messages 2017-12-26 09:58:32 +01:00
2ce9440fdf Use the light update parameter of write_to_map instead of the obsolete update_map (vmanip)
And use minetest.fix_light instead of a custom function (surprisingly it didn't cause a noticeable performance difference)
Also, a few code style changes
2017-12-26 09:39:17 +01:00
12dc8ae004 Fix code style
I've also made a few other changes:
Use minetest.pos_to_string instead of manually creating the string
Do not use table_contains to test if a node id belongs to a nether tree, instead use lua table hashmap behaviour
2017-12-26 09:19:11 +01:00
69b3e65c85 Fix missing unknown node test in grass_allowed 2017-12-26 08:40:18 +01:00
0a2dbbb0f8 Fix small stuff (thanks to warnings from luacheck) 2017-12-25 21:23:34 +01:00
6019bbce66 Do not use old vector_extras functions 2017-12-25 21:22:32 +01:00
acdf694356 Fixes https://github.com/HybridDog/nether-pack/issues/6
```
Use:
local tab = minetest.wrap_text(content, guide_size.fx, true)
Needs 3rd argument 'true' to ensure 'tab' is a table.
See 649eef9e4f/builtin/common/misc_helpers.lua (L311)
```
2017-12-25 20:48:41 +01:00
DS
d32ede7e8a make netherrack and co. digable with creative hand 2017-07-08 14:26:15 +02:00
e8a666f34e replace deprecated setting methods 2017-07-05 18:52:46 +02:00
DS
a7da195aa1 fix a crash caused by the none existing minetest.splittext function
It was replaced with minetest.wrap_text. Hopefully that won't make problems.
2017-07-05 18:38:38 +02:00
afb77f0a1d Update README.md 2017-02-03 23:19:10 +01:00
c33e306849 reduce index calculations (untested)
M  nether/init.lua
2016-09-15 11:57:06 +02:00
dac86dae07 🐈
M  modpack.txt
2016-08-08 15:51:58 +02:00
6d92487f20 🐈 2016-05-26 12:17:06 +02:00
578919c469 fix old newbie mistake 2016-05-04 18:42:45 +02:00
03da51be24 add support to the function delayer mod 2016-05-04 18:36:22 +02:00
b2dd95eb50 Don't use globalsteps 2016-05-04 18:32:17 +02:00
99eceb10eb assume player:getpos always returns a vector
remove patch file
2016-05-04 18:27:36 +02:00
2a3e553b9c fix crash nether if player cancel join server "/nether/portal.lua:243: attempt to index a nil value" 2016-05-04 18:24:57 +02:00
0e9bdc48b2 fix unknow item default:coal 2016-05-04 18:21:40 +02:00
501ce57e59 update readme 2016-05-04 18:18:04 +02:00
3ba23a4c88 New nether guide Much better formspecs based on original code Reworked many sentences 2016-05-04 18:11:02 +02:00
780b95bfbc further optimazion of ws func 2016-05-04 17:43:37 +02:00
f3cec2fe06 🐈 2016-03-10 20:47:16 +01:00
06099dcec3 🐈 2016-02-06 12:04:17 +01:00
b5807be921 use functions from vector_extras which should improve speed 2016-01-10 13:42:16 +01:00
163bd4a021 update nether tree loop, @Ombridride l hope it works for you, and fix missing degrotate paramtype2 of leaves 2016-01-10 12:49:32 +01:00
9cee9d0ec6 🐈 2016-01-04 13:25:06 +01:00
041f1ce21a untested: save known opposite portal y to meta 2016-01-04 12:00:35 +01:00
b8f81b71bc make obsidian portal always work 2016-01-04 11:48:21 +01:00
cacfae9502 add comments and begin making obsidian portal always work 2016-01-04 10:55:39 +01:00
6b57e60e1b smaller pearl 2016-01-01 14:25:07 +01:00
524312a8d3 change nether pearl and portal.lua 2016-01-01 12:39:21 +01:00
6245b9e4e1 allow disabling killing of people using the simple portal 2015-12-31 15:15:39 +01:00
1003e8288c dont send players to hell if they execute those chatcommands without nether priv 2015-12-30 11:16:58 +01:00
a0995f18f8 cache used portals instead of always teleporting to 100 etc 2015-12-28 20:04:38 +01:00
624cf7243d update chatcommand 2015-12-28 19:01:30 +01:00
1e0bcbb709 fix player doesnt hear nether teleporter sound, thanks to @crabman77 2015-12-28 18:38:09 +01:00
40997320b0 add nether fences 2015-12-28 18:06:52 +01:00
8dabe8667a short digging allowed function 2015-12-05 12:39:42 +01:00
8797de8748 add nether torch crafting, make them ingniter and add vine normalmap 2015-12-05 12:28:03 +01:00
2ddf5c81a4 🐈 2015-08-05 10:35:32 +02:00
088d2debd1 🐈 2015-07-18 18:27:02 +02:00
a707932536 🐈 2015-07-18 18:22:28 +02:00
8b9e04d42b 🐈 2015-07-09 20:23:37 +02:00
87f870db57 🐈 2015-07-05 21:01:13 +02:00
b09a30c141 🐈 2015-05-29 12:08:27 +02:00
de4b04f35b l think the texture is not symmetrical enough for 90° rotation 2015-05-27 10:31:27 +02:00
39096975aa …fix one perlin noise outside [-1; 1] problem 2015-05-21 17:29:30 +02:00
314930714b …fix one perlin noise outside [-1; 1] problem 2015-05-21 17:14:54 +02:00
0d07fa3cd4 use the weierstrass function to decorate the nether forest top (similar to http://a.pomf.se/niypzy.png) 2015-05-20 21:01:10 +02:00
21171ceb2c this should fix the problem that nether forest trees often have so many missing leaves 2015-05-20 19:57:51 +02:00
81821263c6 fix mapgen noise mistake (untested) @crabman77 this was the problem l searched @LeMagnesium 2015-05-16 23:49:04 +02:00
79a7754e74 automatic update 2015-04-16 20:41:02 +02:00
79a2e8186b fix nether mapgen 2015-03-19 16:13:24 +01:00
7c75dafcdb at least a bit history 2015-02-18 18:34:03 +01:00
142 changed files with 4186 additions and 1399 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
## Generic ignorable patterns and files
*~
.*.swp
debug.txt

2
LICENSE.txt Normal file
View File

@ -0,0 +1,2 @@
GPLv3 (lkloel's version)
MIT for the changes

11
README.md Normal file
View File

@ -0,0 +1,11 @@
For a description of this Minetest mod, please refer to the forum topic:
https://forum.minetest.net/viewtopic.php?f=9&t=10265
TODO:
* Mapgen: Find a way to get the perlin noise values inside [-1; 1] or use
another noise.
The problem is visible in the nether forest, where the mapgen code flattens
the ceiling if it is very high.
* Mapgen: Generate more detail inside the simple pyramid-like "buildings",
e.g. add a small treasure chest node which contains items

View File

@ -1,3 +0,0 @@
TODO:
— change the portal
— add a teleportation ball

View File

@ -0,0 +1 @@
0

17
nether/.luacheckrc Normal file
View File

@ -0,0 +1,17 @@
read_globals = {
-- Defined by Minetest
"minetest", "vector", "PseudoRandom", "VoxelArea", "ItemStack", "dump",
"string",
-- Mods
"default", "stairs"
}
globals = {"nether"}
ignore = {
"212",
-- Unused argument
"411", "421", "422", "423", "431", "432",
-- Shadowing
}
-- Allow very long lines in guide.lua for the HTML code
files["guide.lua"] = {ignore = {"631"}}

View File

@ -1,199 +0,0 @@
-- Throne of Hades
HADES_THRONE = {
-- Lava Moat
{pos={x=-1,y=-1,z=-1}, block="default:lava_source"},
{pos={x=-1,y=-1,z=0}, block="default:lava_source"},
{pos={x=-1,y=-1,z=1}, block="default:lava_source"},
{pos={x=-1,y=-1,z=2}, block="default:lava_source"},
{pos={x=-1,y=-1,z=3}, block="default:lava_source"},
{pos={x=-1,y=-1,z=4}, block="default:lava_source"},
{pos={x=-1,y=-1,z=5}, block="default:lava_source"},
{pos={x=-1,y=-1,z=6}, block="default:lava_source"},
{pos={x=-1,y=-1,z=7}, block="default:lava_source"},
{pos={x=0,y=-1,z=7}, block="default:lava_source"},
{pos={x=1,y=-1,z=7}, block="default:lava_source"},
{pos={x=2,y=-1,z=7}, block="default:lava_source"},
{pos={x=3,y=-1,z=7}, block="default:lava_source"},
{pos={x=4,y=-1,z=7}, block="default:lava_source"},
{pos={x=5,y=-1,z=7}, block="default:lava_source"},
{pos={x=6,y=-1,z=7}, block="default:lava_source"},
{pos={x=6,y=-1,z=6}, block="default:lava_source"},
{pos={x=6,y=-1,z=5}, block="default:lava_source"},
{pos={x=6,y=-1,z=4}, block="default:lava_source"},
{pos={x=6,y=-1,z=3}, block="default:lava_source"},
{pos={x=6,y=-1,z=2}, block="default:lava_source"},
{pos={x=6,y=-1,z=1}, block="default:lava_source"},
{pos={x=6,y=-1,z=0}, block="default:lava_source"},
{pos={x=6,y=-1,z=-1}, block="default:lava_source"},
{pos={x=5,y=-1,z=-1}, block="default:lava_source"},
{pos={x=4,y=-1,z=-1}, block="default:lava_source"},
{pos={x=3,y=-1,z=-1}, block="default:lava_source"},
{pos={x=2,y=-1,z=-1}, block="default:lava_source"},
{pos={x=1,y=-1,z=-1}, block="default:lava_source"},
{pos={x=0,y=-1,z=-1}, block="default:lava_source"},
-- Floor 1
{pos={x=0,y=0,z=0}, block="nether:netherrack"},
{pos={x=0,y=0,z=1}, block="nether:netherrack"},
{pos={x=0,y=0,z=2}, block="nether:netherrack"},
{pos={x=0,y=0,z=3}, block="nether:netherrack"},
{pos={x=0,y=0,z=4}, block="nether:netherrack"},
{pos={x=0,y=0,z=5}, block="nether:netherrack"},
{pos={x=1,y=0,z=5}, block="nether:netherrack"},
{pos={x=2,y=0,z=5}, block="nether:netherrack"},
{pos={x=3,y=0,z=5}, block="nether:netherrack"},
{pos={x=4,y=0,z=5}, block="nether:netherrack"},
{pos={x=5,y=0,z=5}, block="nether:netherrack"},
{pos={x=0,y=0,z=6}, block="nether:netherrack"},
{pos={x=1,y=0,z=6}, block="nether:netherrack"},
{pos={x=2,y=0,z=6}, block="nether:netherrack"},
{pos={x=3,y=0,z=6}, block="nether:netherrack"},
{pos={x=4,y=0,z=6}, block="nether:netherrack"},
{pos={x=5,y=0,z=6}, block="nether:netherrack"},
{pos={x=5,y=0,z=4}, block="nether:netherrack"},
{pos={x=5,y=0,z=3}, block="nether:netherrack"},
{pos={x=5,y=0,z=2}, block="nether:netherrack"},
{pos={x=5,y=0,z=1}, block="nether:netherrack"},
{pos={x=5,y=0,z=0}, block="nether:netherrack"},
{pos={x=4,y=0,z=0}, block="nether:netherrack"},
{pos={x=3,y=0,z=0}, block="nether:netherrack"},
{pos={x=2,y=0,z=0}, block="nether:netherrack"},
{pos={x=1,y=0,z=0}, block="nether:netherrack"},
-- Floor 2
{pos={x=0,y=1,z=0}, block="nether:netherrack"},
{pos={x=0,y=1,z=1}, block="nether:netherrack"},
{pos={x=0,y=1,z=2}, block="nether:netherrack"},
{pos={x=0,y=1,z=3}, block="nether:netherrack"},
{pos={x=0,y=1,z=4}, block="nether:netherrack"},
{pos={x=0,y=1,z=5}, block="nether:netherrack"},
{pos={x=1,y=1,z=5}, block="nether:netherrack"},
{pos={x=2,y=1,z=5}, block="nether:netherrack"},
{pos={x=3,y=1,z=5}, block="nether:netherrack"},
{pos={x=4,y=1,z=5}, block="nether:netherrack"},
{pos={x=5,y=1,z=5}, block="nether:netherrack"},
{pos={x=0,y=1,z=6}, block="nether:netherrack"},
{pos={x=1,y=1,z=6}, block="nether:netherrack"},
{pos={x=2,y=1,z=6}, block="nether:netherrack"},
{pos={x=3,y=1,z=6}, block="nether:netherrack"},
{pos={x=4,y=1,z=6}, block="nether:netherrack"},
{pos={x=5,y=1,z=6}, block="nether:netherrack"},
{pos={x=5,y=1,z=4}, block="nether:netherrack"},
{pos={x=5,y=1,z=3}, block="nether:netherrack"},
{pos={x=5,y=1,z=2}, block="nether:netherrack"},
{pos={x=5,y=1,z=1}, block="nether:netherrack"},
{pos={x=5,y=1,z=0}, block="nether:netherrack"},
{pos={x=4,y=1,z=0}, block="nether:netherrack"},
{pos={x=3,y=1,z=1}, block="nether:netherrack"},
{pos={x=2,y=1,z=1}, block="nether:netherrack"},
{pos={x=1,y=1,z=0}, block="nether:netherrack"},
{pos={x=1,y=1,z=1}, block="nether:netherrack"},
{pos={x=4,y=1,z=1}, block="nether:netherrack"},
-- Floor 3
{pos={x=0,y=2,z=0}, block="nether:netherrack"},
{pos={x=0,y=2,z=1}, block="nether:netherrack"},
{pos={x=0,y=2,z=2}, block="nether:netherrack"},
{pos={x=0,y=2,z=3}, block="nether:netherrack"},
{pos={x=0,y=2,z=4}, block="nether:netherrack"},
{pos={x=0,y=2,z=5}, block="nether:netherrack"},
{pos={x=1,y=2,z=5}, block="nether:netherrack"},
{pos={x=2,y=2,z=5}, block="nether:netherrack"},
{pos={x=3,y=2,z=5}, block="nether:netherrack"},
{pos={x=4,y=2,z=5}, block="nether:netherrack"},
{pos={x=5,y=2,z=5}, block="nether:netherrack"},
{pos={x=0,y=2,z=6}, block="nether:netherrack"},
{pos={x=1,y=2,z=6}, block="nether:netherrack"},
{pos={x=2,y=2,z=6}, block="nether:netherrack"},
{pos={x=3,y=2,z=6}, block="nether:netherrack"},
{pos={x=4,y=2,z=6}, block="nether:netherrack"},
{pos={x=5,y=2,z=6}, block="nether:netherrack"},
{pos={x=5,y=2,z=4}, block="nether:netherrack"},
{pos={x=5,y=2,z=3}, block="nether:netherrack"},
{pos={x=5,y=2,z=2}, block="nether:netherrack"},
{pos={x=5,y=2,z=1}, block="nether:netherrack"},
{pos={x=5,y=2,z=0}, block="nether:netherrack"},
{pos={x=4,y=2,z=0}, block="nether:netherrack"},
{pos={x=3,y=2,z=2}, block="nether:netherrack"},
{pos={x=2,y=2,z=2}, block="nether:netherrack"},
{pos={x=1,y=2,z=0}, block="nether:netherrack"},
{pos={x=1,y=2,z=1}, block="nether:netherrack"},
{pos={x=4,y=2,z=1}, block="nether:netherrack"},
{pos={x=1,y=2,z=2}, block="nether:netherrack"},
{pos={x=4,y=2,z=2}, block="nether:netherrack"},
-- Floor 4
{pos={x=0,y=3,z=0}, block="nether:netherrack"},
{pos={x=0,y=3,z=1}, block="nether:netherrack"},
{pos={x=0,y=3,z=2}, block="nether:netherrack"},
{pos={x=0,y=3,z=3}, block="nether:netherrack"},
{pos={x=0,y=3,z=4}, block="nether:netherrack"},
{pos={x=0,y=3,z=5}, block="nether:netherrack"},
{pos={x=1,y=3,z=5}, block="nether:netherrack"},
{pos={x=2,y=3,z=5}, block="nether:netherrack"},
{pos={x=3,y=3,z=5}, block="nether:netherrack"},
{pos={x=4,y=3,z=5}, block="nether:netherrack"},
{pos={x=5,y=3,z=5}, block="nether:netherrack"},
{pos={x=0,y=3,z=6}, block="nether:netherrack"},
{pos={x=1,y=3,z=6}, block="nether:netherrack"},
{pos={x=2,y=3,z=6}, block="nether:netherrack"},
{pos={x=3,y=3,z=6}, block="nether:netherrack"},
{pos={x=4,y=3,z=6}, block="nether:netherrack"},
{pos={x=5,y=3,z=6}, block="nether:netherrack"},
{pos={x=5,y=3,z=4}, block="nether:netherrack"},
{pos={x=5,y=3,z=3}, block="nether:netherrack"},
{pos={x=5,y=3,z=2}, block="nether:netherrack"},
{pos={x=5,y=3,z=1}, block="nether:netherrack"},
{pos={x=5,y=3,z=0}, block="nether:netherrack"},
{pos={x=4,y=3,z=0}, block="nether:netherrack"},
{pos={x=3,y=3,z=3}, block="nether:netherrack"},
{pos={x=2,y=3,z=3}, block="nether:netherrack"},
{pos={x=1,y=3,z=0}, block="nether:netherrack"},
{pos={x=1,y=3,z=1}, block="nether:netherrack"},
{pos={x=4,y=3,z=1}, block="nether:netherrack"},
{pos={x=1,y=3,z=2}, block="nether:netherrack"},
{pos={x=4,y=3,z=2}, block="nether:netherrack"},
{pos={x=1,y=3,z=3}, block="nether:netherrack"},
{pos={x=4,y=3,z=3}, block="nether:netherrack"},
{pos={x=1,y=3,z=4}, block="nether:netherrack"},
{pos={x=4,y=3,z=4}, block="nether:netherrack"},
{pos={x=2,y=3,z=4}, block="nether:netherrack"},
{pos={x=2,y=3,z=5}, block="nether:netherrack"},
{pos={x=3,y=3,z=4}, block="nether:netherrack"},
{pos={x=3,y=3,z=5}, block="nether:netherrack"},
-- Floor 5
{pos={x=2,y=4,z=4}, block="nether:netherrack"},
{pos={x=2,y=4,z=5}, block="nether:netherrack"},
{pos={x=3,y=4,z=4}, block="nether:netherrack"},
{pos={x=3,y=4,z=5}, block="nether:netherrack"},
{pos={x=2,y=4,z=6}, block="nether:netherrack"},
{pos={x=3,y=4,z=6}, block="nether:netherrack"},
-- Torches on floor 5
{pos={x=0,y=4,z=4}, block="nether:torch_bottom"},
{pos={x=1,y=4,z=4}, block="nether:torch_bottom"},
{pos={x=0,y=4,z=5}, block="nether:torch_bottom"},
{pos={x=1,y=4,z=5}, block="nether:torch_bottom"},
{pos={x=4,y=4,z=4}, block="nether:torch_bottom"},
{pos={x=5,y=4,z=4}, block="nether:torch_bottom"},
{pos={x=4,y=4,z=5}, block="nether:torch_bottom"},
{pos={x=5,y=4,z=5}, block="nether:torch_bottom"},
{pos={x=0,y=4,z=0}, block="nether:torch_bottom"},
{pos={x=1,y=4,z=0}, block="nether:torch_bottom"},
{pos={x=0,y=4,z=1}, block="nether:torch_bottom"},
{pos={x=1,y=4,z=1}, block="nether:torch_bottom"},
{pos={x=4,y=4,z=0}, block="nether:torch_bottom"},
{pos={x=5,y=4,z=0}, block="nether:torch_bottom"},
{pos={x=4,y=4,z=1}, block="nether:torch_bottom"},
{pos={x=5,y=4,z=1}, block="nether:torch_bottom"},
{pos={x=0,y=4,z=2}, block="nether:torch_bottom"},
{pos={x=1,y=4,z=2}, block="nether:torch_bottom"},
{pos={x=0,y=4,z=3}, block="nether:torch_bottom"},
{pos={x=1,y=4,z=3}, block="nether:torch_bottom"},
{pos={x=4,y=4,z=2}, block="nether:torch_bottom"},
{pos={x=5,y=4,z=2}, block="nether:torch_bottom"},
{pos={x=4,y=4,z=3}, block="nether:torch_bottom"},
{pos={x=5,y=4,z=3}, block="nether:torch_bottom"},
{pos={x=4,y=4,z=6}, block="nether:torch_bottom"},
{pos={x=5,y=4,z=6}, block="nether:torch_bottom"},
{pos={x=0,y=4,z=6}, block="nether:torch_bottom"},
{pos={x=1,y=4,z=6}, block="nether:torch_bottom"},
-- Nether Portal
{pos={x=1,y=5,z=6}, portalblock=true},
}

157
nether/common.lua Normal file
View File

@ -0,0 +1,157 @@
dofile(nether.path .. "/settings.lua")
local in_mapgen_env = nether.env_type == "ssm_mapgen"
-- vars
nether.v = {}
local v = nether.v
--== EDITABLE OPTIONS ==--
-- Depth of the nether
v.nether_middle = -20000
-- forest bottom perlin multiplication
v.f_bottom_scale = 4
-- forest bottom height
v.f_h_min = v.nether_middle+10
-- forest top height
v.f_h_max = v.f_h_min+250
-- Frequency of trees in the nether forest (higher is less frequent)
v.tree_rarity = 200
-- Frequency of glowflowers in the nether forest (higher is less frequent)
v.glowflower_rarity = 120
-- Frequency of nether grass in the nether forest (higher is less frequent)
v.grass_rarity = 2
-- Frequency of nether mushrooms in the nether forest (higher is less frequent)
v.mushroom_rarity = 80
v.abm_tree_interval = 864
v.abm_tree_chance = 100
-- height of the nether generation's end
v.nether_start = v.f_h_max+100
-- Height of the nether (bottom of the nether is nether_middle - NETHER_HEIGHT)
v.NETHER_HEIGHT = 30
-- bottom height of the nether.
v.nether_bottom = v.nether_middle - v.NETHER_HEIGHT - 100
-- Maximum amount of randomness in the map generation
v.NETHER_RANDOM = 2
-- Frequency of Glowstone on the "roof" of the Nether (higher is less frequent)
v.GLOWSTONE_FREQ_ROOF = 500
-- Frequency of lava (higher is less frequent)
v.LAVA_FREQ = 100
v.nether_structure_freq = 350
v.NETHER_SHROOM_FREQ = 100
-- Maximum height of lava
--v.LAVA_HEIGHT = 2
-- Frequency of Glowstone on lava (higher is less frequent)
--v.GLOWSTONE_FREQ_LAVA = 2
-- Height of nether structures
--v.NETHER_TREESIZE = 2
-- Frequency of apples in a nether structure (higher is less frequent)
--v.NETHER_APPLE_FREQ = 5
-- Frequency of healing apples in a nether structure (higher is less frequent)
--v.NETHER_HEAL_APPLE_FREQ = 10
-- Start position for the Throne of Hades (y is relative to the bottom of the
-- nether)
--v.HADES_THRONE_STARTPOS = {x=0, y=1, z=0}
-- Spawn pos for when the nether hasn't been loaded yet (i.e. no portal in the
-- nether) (y is relative to the bottom of the nether)
--v.NETHER_SPAWNPOS = {x=0, y=5, z=0}
-- Structure of the nether portal (all is relative to the nether portal creator
-- block)
--== END OF EDITABLE OPTIONS ==--
-- Generated variables
v.NETHER_BOTTOM = (v.nether_middle - v.NETHER_HEIGHT)
v.nether_buildings = v.NETHER_BOTTOM+12
function nether.query_contents()
local c = {
ignore = minetest.get_content_id("ignore"),
air = minetest.get_content_id("air"),
lava = minetest.get_content_id("default:lava_source"),
gravel = minetest.get_content_id("default:gravel"),
coal = minetest.get_content_id("default:stone_with_coal"),
diamond = minetest.get_content_id("default:stone_with_diamond"),
mese = minetest.get_content_id("default:mese"),
--https://github.com/Zeg9/minetest-glow
glowstone = minetest.get_content_id("glow:stone"),
nether_shroom = minetest.get_content_id("riesenpilz:nether_shroom"),
netherrack = minetest.get_content_id("nether:netherrack"),
netherrack_tiled = minetest.get_content_id("nether:netherrack_tiled"),
netherrack_black = minetest.get_content_id("nether:netherrack_black"),
netherrack_blue = minetest.get_content_id("nether:netherrack_blue"),
netherrack_brick = minetest.get_content_id("nether:netherrack_brick"),
white = minetest.get_content_id("nether:white"),
nether_vine = minetest.get_content_id("nether:vine"),
blood = minetest.get_content_id("nether:blood"),
blood_top = minetest.get_content_id("nether:blood_top"),
blood_stem = minetest.get_content_id("nether:blood_stem"),
nether_apple = minetest.get_content_id("nether:apple"),
nether_tree = minetest.get_content_id("nether:tree"),
nether_tree_corner = minetest.get_content_id("nether:tree_corner"),
nether_leaves = minetest.get_content_id("nether:leaves"),
nether_grass = {
minetest.get_content_id("nether:grass_small"),
minetest.get_content_id("nether:grass_middle"),
minetest.get_content_id("nether:grass_big")
},
glowflower = minetest.get_content_id("nether:glowflower"),
nether_dirt = minetest.get_content_id("nether:dirt"),
nether_dirt_top = minetest.get_content_id("nether:dirt_top"),
nether_dirt_bottom = minetest.get_content_id("nether:dirt_bottom"),
}
local trn = {c.nether_tree, c.nether_tree_corner, c.nether_leaves,
c.nether_fruit}
local nether_tree_nodes = {}
for i = 1,#trn do
nether_tree_nodes[trn[i]] = true
end
return c, nether_tree_nodes
end
if nether.log_level >= 1 then
local mod_prefix = in_mapgen_env and "[nether(mg)] " or "[nether] "
function nether:inform(msg, spam, t)
if spam <= self.log_level then
local info
if t then
info = mod_prefix .. msg .. (" after ca. %.3g s"):format(
(minetest.get_us_time() - t) / 1000000)
else
info = mod_prefix .. msg
end
print(info)
if self.log_to_chat then
minetest.chat_send_all(info)
end
end
end
else
function nether.inform()
end
end

253
nether/crafting.lua Normal file
View File

@ -0,0 +1,253 @@
minetest.register_craft({
output = "nether:fim",
recipe = {
{"nether:shroom_head"},
{"nether:fruit_no_leaf"},
{"nether:shroom_head"},
}
})
minetest.register_craft({
output = "nether:fruit_leaves",
recipe = {
{"nether:fruit_leaf", "nether:fruit_leaf", "nether:fruit_leaf"},
{"nether:fruit_leaf", "nether:fruit_leaf", "nether:fruit_leaf"},
{"nether:fruit_leaf", "nether:fruit_leaf", "nether:fruit_leaf"},
}
})
minetest.register_craft({
output = "nether:pick_mushroom",
recipe = {
{"nether:shroom_head", "nether:shroom_head", "nether:shroom_head"},
{"", "nether:shroom_stem", ""},
{"", "nether:shroom_stem", ""},
}
})
minetest.register_craft({
output = "nether:pick_wood",
recipe = {
{"nether:wood_cooked", "nether:wood_cooked", "nether:wood_cooked"},
{"", "group:stick", ""},
{"", "group:stick", ""},
}
})
for _,m in pairs({"netherrack", "netherrack_blue", "white"}) do
local input = "nether:"..m
minetest.register_craft({
output = "nether:pick_"..m,
recipe = {
{input, input, input},
{"", "group:stick", ""},
{"", "group:stick", ""},
}
})
minetest.register_craft({
output = "nether:axe_"..m,
recipe = {
{input, input},
{input, "group:stick"},
{"", "group:stick"},
}
})
minetest.register_craft({
output = "nether:sword_"..m,
recipe = {
{input},
{input},
{"group:stick"},
}
})
minetest.register_craft({
output = "nether:shovel_"..m,
recipe = {
{input},
{"group:stick"},
{"group:stick"},
}
})
end
minetest.register_craft({
output = "nether:netherrack_brick 4",
recipe = {
{"nether:netherrack", "nether:netherrack"},
{"nether:netherrack", "nether:netherrack"},
}
})
minetest.register_craft({
output = "nether:netherrack_brick_black 4",
recipe = {
{"nether:netherrack_black", "nether:netherrack_black"},
{"nether:netherrack_black", "nether:netherrack_black"},
}
})
minetest.register_craft({
output = "nether:netherrack_brick_blue 4",
recipe = {
{"nether:netherrack_blue", "nether:netherrack_blue"},
{"nether:netherrack_blue", "nether:netherrack_blue"},
}
})
minetest.register_craft({
output = "default:furnace",
recipe = {
{"nether:netherrack_brick", "nether:netherrack_brick", "nether:netherrack_brick"},
{"nether:netherrack_brick", "", "nether:netherrack_brick"},
{"nether:netherrack_brick", "nether:netherrack_brick", "nether:netherrack_brick"},
}
})
minetest.register_craft({
output = "nether:extractor",
recipe = {
{"nether:netherrack_brick", "nether:blood_top_cooked", "nether:netherrack_brick"},
{"nether:blood_cooked", "nether:shroom_stem", "nether:blood_cooked"},
{"nether:netherrack_brick", "nether:blood_stem_cooked", "nether:netherrack_brick"},
}
})
minetest.register_craft({
output = "nether:wood 4",
recipe = {
{"nether:blood_stem"},
}
})
minetest.register_craft({
output = "nether:wood_empty 4",
recipe = {
{"nether:blood_stem_empty"},
}
})
minetest.register_craft({
output = "nether:stick 4",
recipe = {
{"nether:wood_empty"},
}
})
minetest.register_craft({
output = "nether:torch",
recipe = {
{"nether:bark"},
{"group:stick"},
}
})
minetest.register_craft({
output = "nether:forest_wood",
recipe = {
{"nether:forest_planks", "nether:forest_planks", "nether:forest_planks"},
{"nether:forest_planks", "", "nether:forest_planks"},
{"nether:forest_planks", "nether:forest_planks", "nether:forest_planks"},
}
})
minetest.register_craft({
output = "nether:forest_planks 8",
recipe = {
{"nether:forest_wood"},
}
})
minetest.register_craft({
output = "nether:forest_planks 7",
recipe = {
{"nether:tree"},
},
})
local sound_allowed = true
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
if itemstack:get_name() ~= "nether:forest_planks"
or itemstack:get_count() ~= 7 then
return
end
local tree
for i = 1,9 do
if old_craft_grid[i]:get_name() == "nether:tree" then
tree = i
break
end
end
if not tree then -- do nth if theres no tree
return
end
local rdif = math.random(-1,1) -- add a bit randomness
local barkstack = ItemStack("nether:bark "..4-rdif)
local inv = player:get_inventory()
if not inv:room_for_item("main", barkstack) then -- disallow crafting if there's not enough free space
craft_inv:set_list("craft", old_craft_grid)
itemstack:set_name("")
return
end
itemstack:set_count(7+rdif)
inv:add_item("main", barkstack)
if not sound_allowed then -- avoid playing the sound multiple times, e.g. when middle mouse click
return
end
minetest.sound_play("default_wood_footstep", {pos=player:get_pos(), gain=0.25})
sound_allowed = false
minetest.after(0, function()
sound_allowed = true
end)
end)
minetest.register_craft({
output = "default:paper",
recipe = {
{"nether:grass_dried", "nether:grass_dried", "nether:grass_dried"},
}
})
minetest.register_craft({
type = "cooking",
output = "default:coal_lump",
recipe = "nether:tree",
})
minetest.register_craft({
type = "cooking",
output = "nether:grass_dried",
recipe = "nether:grass",
})
minetest.register_craft({
type = "cooking",
output = "nether:pearl",
recipe = "nether:fim",
})
minetest.register_craft({
type = "cooking",
output = "nether:hotbed",
recipe = "nether:blood_extracted",
})
for _,i in ipairs({"nether:blood", "nether:blood_top", "nether:blood_stem", "nether:wood"}) do
local cooked = i.."_cooked"
minetest.register_craft({
type = "cooking",
output = cooked,
recipe = i,
})
minetest.register_craft({
type = "fuel",
recipe = cooked,
burntime = 30,
})
end

View File

@ -1,3 +0,0 @@
default
riesenpilz
glow

346
nether/furnace.lua Normal file
View File

@ -0,0 +1,346 @@
-- minetest time speed
local time_speed = tonumber(minetest.settings:get("time_speed"))
if not time_speed then
time_speed = 1
else
time_speed = time_speed/72
end
local function get_date()
return os.date("%y %d %H %M %S")
end
-- returns the time difference in seconds
local function get_timediff(d1, d2)
local d = string.split(d1, " ")
for n,i in pairs(string.split(d2, " ")) do
d[n] = i-d[n]
end
local secs = 0
local y,d,h,m,s = unpack(d)
if s ~= 0 then
secs = secs+s
end
if m ~= 0 then
secs = secs+m*60
end
if h ~= 0 then
secs = secs+h*3600 -- 60*60
end
if d ~= 0 then
secs = secs+d*86400 -- 60*60*24
end
if y ~= 0 then
secs = secs+y*31557600 -- 60*60*24*365.25
end
--secs = math.floor(secs+0.5)
if secs < 0 then
minetest.log("action", "play warzone2100?")
end
return secs*time_speed
end
-- copied from older default furnace code and edited a bit
function nether.get_furnace_active_formspec(pos, percent)
local formspec =
"size[8,9]"..
"image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
(100-percent)..":default_furnace_fire_fg.png]"..
"list[current_name;fuel;2,3;1,1;]"..
"list[current_name;src;2,1;1,1;]"..
"list[current_name;dst;5,1;2,2;]"..
"list[current_player;main;0,5;8,4;]"
return formspec
end
nether.furnace_inactive_formspec =
"size[8,9]"..
"image[2,2;1,1;default_furnace_fire_bg.png]"..
"list[current_name;fuel;2,3;1,1;]"..
"list[current_name;src;2,1;1,1;]"..
"list[current_name;dst;5,1;2,2;]"..
"list[current_player;main;0,5;8,4;]"
minetest.register_node("nether:furnace", {
description = "Furnace",
tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
paramtype2 = "facedir",
groups = {cracky=2},
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", nether.furnace_inactive_formspec)
meta:set_string("infotext", "Furnace")
local inv = meta:get_inventory()
inv:set_size("fuel", 1)
inv:set_size("src", 1)
inv:set_size("dst", 4)
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
if not inv:is_empty("fuel") then
return false
elseif not inv:is_empty("dst") then
return false
elseif not inv:is_empty("src") then
return false
end
return true
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
meta:set_string("last_active", get_date())
local inv = meta:get_inventory()
if listname == "fuel" then
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext","Furnace is empty")
end
return stack:get_count()
else
return 0
end
elseif listname == "src" then
return stack:get_count()
elseif listname == "dst" then
return 0
end
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
meta:set_string("last_active", get_date())
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
if to_list == "fuel" then
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext","Furnace is empty")
end
return count
else
return 0
end
elseif to_list == "src" then
return count
elseif to_list == "dst" then
return 0
end
end,
})
minetest.register_node("nether:furnace_active", {
description = "Furnace",
tiles = {
"default_furnace_top.png",
"default_furnace_bottom.png",
"default_furnace_side.png",
"default_furnace_side.png",
"default_furnace_side.png",
{
image = "default_furnace_front_active.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1.5
},
}
},
paramtype2 = "facedir",
light_source = 8,
drop = "nether:furnace",
groups = {cracky=2, not_in_creative_inventory=1,hot=1},
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", nether.furnace_inactive_formspec)
meta:set_string("infotext", "Furnace");
local inv = meta:get_inventory()
inv:set_size("fuel", 1)
inv:set_size("src", 1)
inv:set_size("dst", 4)
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
if not inv:is_empty("fuel") then
return false
elseif not inv:is_empty("dst") then
return false
elseif not inv:is_empty("src") then
return false
end
return true
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
meta:set_string("last_active", get_date())
local inv = meta:get_inventory()
if listname == "fuel" then
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext","Furnace is empty")
end
return stack:get_count()
else
return 0
end
elseif listname == "src" then
return stack:get_count()
elseif listname == "dst" then
return 0
end
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
meta:set_string("last_active", get_date())
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
if to_list == "fuel" then
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext","Furnace is empty")
end
return count
else
return 0
end
elseif to_list == "src" then
return count
elseif to_list == "dst" then
return 0
end
end,
})
local function swap_node(pos,name)
local node = minetest.get_node(pos)
if node.name == name then
return
end
node.name = name
minetest.swap_node(pos,node)
end
minetest.register_abm({
nodenames = {"nether:furnace","nether:furnace_active"},
interval = 1.0,
chance = 1,
action = function(pos)
local meta = minetest.get_meta(pos)
if meta:get_string("timedif") == "" then
meta:set_float("timedif", 0.0)
end
-- lag shouldn't control the furnace speed
local current_time = get_date()
local last_time = meta:get_string("last_active")
if last_time == "" then
meta:set_string("last_active", current_time)
return
end
if last_time == current_time then
return
end
local timediff = get_timediff(last_time, current_time)+meta:get_string("timedif")
local times = math.floor(timediff)
meta:set_string("last_active", current_time)
meta:set_float("timedif", timediff-times)
for _ = 1,times do
for _,name in pairs({
"fuel_totaltime",
"fuel_time",
"src_totaltime",
"src_time",
}) do
if meta:get_string(name) == "" then
meta:set_float(name, 0.0)
end
end
local inv = meta:get_inventory()
local srclist = inv:get_list("src")
local cooked = nil
local aftercooked
if srclist then
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
end
local was_active = false
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
was_active = true
meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
meta:set_float("src_time", meta:get_float("src_time") + 1)
if cooked
and cooked.item
and meta:get_float("src_time") >= cooked.time then
-- check if there's room for output in "dst" list
if inv:room_for_item("dst",cooked.item) then
-- Put result in "dst" list
inv:add_item("dst", cooked.item)
-- take stuff from "src" list
inv:set_stack("src", 1, aftercooked.items[1])
--~ else
--print("Could not insert '"..cooked.item:to_string().."'")
end
meta:set_string("src_time", 0)
end
end
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
local percent = math.floor(meta:get_float("fuel_time") /
meta:get_float("fuel_totaltime") * 100)
meta:set_string("infotext","Furnace active: "..percent.."%")
swap_node(pos,"nether:furnace_active")
meta:set_string("formspec",nether.get_furnace_active_formspec(pos, percent))
return
end
local fuel = nil
local afterfuel
local cooked = nil
local fuellist = inv:get_list("fuel")
local srclist = inv:get_list("src")
if srclist then
cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
end
if fuellist then
fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
end
if not fuel or fuel.time <= 0 then
meta:set_string("infotext","Furnace out of fuel")
swap_node(pos,"nether:furnace")
meta:set_string("formspec", nether.furnace_inactive_formspec)
return
end
if cooked.item:is_empty() then
if was_active then
meta:set_string("infotext","Furnace is empty")
swap_node(pos,"nether:furnace")
meta:set_string("formspec", nether.furnace_inactive_formspec)
end
return
end
meta:set_string("fuel_totaltime", fuel.time)
meta:set_string("fuel_time", 0)
inv:set_stack("fuel", 1, afterfuel.items[1])
end
end,
})

312
nether/grow_structures.lua Normal file
View File

@ -0,0 +1,312 @@
local netherstructure_height = 6
local function vmanip_with_r_area(width, height, pos)
local manip = minetest.get_voxel_manip()
local emerged_pos1, emerged_pos2 = manip:read_from_map(
{x=pos.x-width, y=pos.y, z=pos.z-width},
{x=pos.x+width, y=pos.y+height, z=pos.z+width}
)
return manip, VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
end
local function inform_grow(pos, t1, name, generated)
nether:inform(name.." grew at " .. minetest.pos_to_string(pos),
generated and 3 or 2, t1)
end
local function set_vm_data(manip, nodes, pos, t1, name, generated)
manip:set_data(nodes)
manip:write_to_map(not generated)
inform_grow(pos, t1, name, generated)
end
local c, contents_defined
local function define_contents()
if not contents_defined then
c = nether.query_contents()
contents_defined = true
end
end
local function grow_netherstructure_into_raw(area, nodes, pos, generated)
define_contents()
local height = netherstructure_height
local vi = area:indexp(pos)
for _ = 0, height-1 do
nodes[vi] = c.blood_stem
vi = vi + area.ystride
end
for i = -1,1 do
for j = -1,1 do
nodes[area:index(pos.x+i, pos.y+height, pos.z+j)] = c.blood_top
end
end
for k = -1, 1, 2 do
for l = -2+1, 2 do
local p1 = {pos.x+2*k, pos.y+height, pos.z-l*k}
local p2 = {pos.x+l*k, pos.y+height, pos.z+2*k}
local udat = c.blood_top
if math.random(2) == 1 then
nodes[area:index(p1[1], p1[2], p1[3])] = c.blood_top
nodes[area:index(p2[1], p2[2], p2[3])] = c.blood_top
udat = c.blood
end
nodes[area:index(p1[1], p1[2]-1, p1[3])] = udat
nodes[area:index(p2[1], p2[2]-1, p2[3])] = udat
end
for l = 0, 1 do
for _,p in ipairs({
{pos.x+k, pos.y+height-1, pos.z-l*k},
{pos.x+l*k, pos.y+height-1, pos.z+k},
}) do
if math.random(2) == 1 then
nodes[area:index(p[1], p[2], p[3])] = c.nether_apple
--elseif math.random(10) == 1 then
-- nodes[area:index(p[1], p[2], p[3])] = c.apple
end
end
end
end
end
function nether.grow_netherstructure_into(area, nodes, pos, generated)
local t1 = minetest.get_us_time()
if not pos.x then print(dump(pos))
nether:inform("Error: "..dump(pos), 1)
return
end
grow_netherstructure_into_raw(area, nodes, pos, generated)
inform_grow(pos, t1, "blood", generated)
end
function nether.grow_netherstructure(pos, generated)
local t1 = minetest.get_us_time()
if not pos.x then print(dump(pos))
nether:inform("Error: "..dump(pos), 1)
return
end
local height = netherstructure_height
local manip, area = vmanip_with_r_area(2, height, pos)
local nodes = manip:get_data()
grow_netherstructure_into_raw(area, nodes, pos, generated)
set_vm_data(manip, nodes, pos, t1, "blood", generated)
end
local poshash = minetest.hash_node_position
local pos_from_hash = minetest.get_position_from_hash
local function soft_node(id)
return id == c.air or id == c.ignore
end
local function update_minmax(min, max, p)
min.x = math.min(min.x, p.x)
max.x = math.max(max.x, p.x)
min.z = math.min(min.z, p.z)
max.z = math.max(max.z, p.z)
end
local fruit_chances = {}
for y = -2,1 do --like a hyperbola
fruit_chances[y] = math.floor(-4/(y-2)+0.5)
end
local dirs = {
{-1, 0, 12, 19},
{1, 0, 12, 13},
{0, 1, 4},
{0, -1, 4, 10},
}
local h_max = 26
local h_stem_min = 3
local h_stem_max = 7
local h_arm_min = 2
local h_arm_max = 6
local r_arm_min = 1
local r_arm_max = 5
local fruit_rarity = 25 --a bigger number results in less fruits
local leaf_thickness = 3 --a bigger number results in more blank trees
local h_trunk_max = h_max-h_arm_max
function nether.grow_tree(pos, generated)
local t1 = minetest.get_us_time()
define_contents()
local min = vector.new(pos)
local max = vector.new(pos)
min.y = min.y-1
max.y = max.y+h_max
local trunks = {}
local trunk_corners = {}
local h_stem = math.random(h_stem_min, h_stem_max)
local todo,n = {{x=pos.x, y=pos.y+h_stem, z=pos.z}},1
while n do
local p = todo[n]
todo[n] = nil
n = next(todo)
local used_dirs,u = {},1
for _,dir in pairs(dirs) do
if math.random(1,2) == 1 then
used_dirs[u] = dir
u = u+1
end
end
if not used_dirs[1] then
local dir1 = math.random(4)
local dir2 = math.random(3)
if dir1 <= dir2 then
dir2 = dir2+1
end
used_dirs[1] = dirs[dir1]
used_dirs[2] = dirs[dir2]
end
for _,dir in pairs(used_dirs) do
local p = vector.new(p)
local r = math.random(r_arm_min, r_arm_max)
for j = 1,r do
local x = p.x+j*dir[1]
local z = p.z+j*dir[2]
trunks[poshash{x=x, y=p.y, z=z}] = dir[3]
end
r = r+1
p.x = p.x+r*dir[1]
p.z = p.z+r*dir[2]
trunk_corners[poshash(p)] = dir[4] or dir[3]
local h = math.random(h_arm_min, h_arm_max)
for i = 1,h do
p.y = p.y + i
trunks[poshash(p)] = true
p.y = p.y - i
end
p.y = p.y+h
--n = #todo+1 -- caused small trees
todo[#todo+1] = p
end
if p.y > pos.y+h_trunk_max then
break
end
n = n or next(todo)
end
local leaves = {}
local fruits = {}
local trunk_ps = {}
local count = 0
local ps = {}
local trunk_count = 0
for i,par2 in pairs(trunks) do
local pos = pos_from_hash(i)
update_minmax(min, max, pos)
local z,y,x = pos.z, pos.y, pos.x
trunk_count = trunk_count+1
ps[trunk_count] = {z,y,x, par2}
end
for _,d in pairs(ps) do
if d[4] == true then
d[4] = nil
end
trunk_ps[#trunk_ps+1] = d
local pz, py, px = unpack(d)
count = count+1
if count > leaf_thickness then
count = 0
for y = -2,2 do
local fruit_chance = fruit_chances[y]
for z = -2,2 do
for x = -2,2 do
local distq = x*x+y*y+z*z
if distq ~= 0
and math.random(1, math.sqrt(distq)) == 1 then
local x = x+px
local y = y+py
local z = z+pz
local vi = poshash{x=x, y=y, z=z}
if not trunks[vi] then
if fruit_chance
and math.random(1, fruit_rarity) == 1
and math.random(1, fruit_chance) == 1 then
fruits[vi] = true
else
leaves[vi] = true
end
update_minmax(min, max, {x=x, z=z})
end
end
end
end
end
end
end
--ps = nil
--collectgarbage()
for i = -1,h_stem+1 do
-- param2 explicitly set 0 due to possibly previous leaves node
trunk_ps[#trunk_ps+1] = {pos.z, pos.y+i, pos.x, 0}
end
local manip = minetest.get_voxel_manip()
local emerged_pos1, emerged_pos2 = manip:read_from_map(min, max)
local area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
local nodes = manip:get_data()
local param2s = manip:get_param2_data()
for i in pairs(leaves) do
local p = area:indexp(pos_from_hash(i))
if soft_node(nodes[p]) then
nodes[p] = c.nether_leaves
param2s[p] = math.random(0,179)
--param2s[p] = math.random(0,44)
end
end
for i in pairs(fruits) do
local p = area:indexp(pos_from_hash(i))
if soft_node(nodes[p]) then
nodes[p] = c.nether_apple
end
end
for i = 1,#trunk_ps do
local p = trunk_ps[i]
local par = p[4]
p = area:index(p[3], p[2], p[1])
if par then
param2s[p] = par
end
nodes[p] = c.nether_tree
end
for i,par2 in pairs(trunk_corners) do
local vi = area:indexp(pos_from_hash(i))
nodes[vi] = c.nether_tree_corner
param2s[vi] = par2
end
manip:set_data(nodes)
manip:set_param2_data(param2s)
manip:write_to_map(not generated)
nether:inform("a nether tree with " .. trunk_count ..
" branch trunk nodes grew at " .. minetest.pos_to_string(pos),
generated and 3 or 2, t1)
end

276
nether/guide.lua Normal file
View File

@ -0,0 +1,276 @@
-- The content of the guide
local guide_infos = {
{"Nether Mushroom",
[[Nether mushrooms can be found on the nether's ground and on Dirty Netherrack. They can be dug by hand.
<item name=riesenpilz:nether_shroom width=100>
<my_h2><b>Crafting Items</b></my_h2>
If we drop a Nether mushroom without holding the fast key, we can split it into its stem and head. We can use them to craft a Nether Mushroom Pickaxe, a Nether Blood Extractor, and an uncooked Nether Pearl.
<item name=nether:shroom_head width=100> <item name=nether:shroom_stem width=100>
<my_h2><b>Cultivating Mushrooms</b></my_h2>
We can get more mushrooms using Dirty Netherrack:
1. Search a dark place (light level <= 7) and, if necessary, place Netherrack with air above it
<img name=nether_netherrack.png width=100>
2. Right click with Cooked Blood onto the Netherrack to turn it into Dirty Netherrack
<item name=nether:hotbed width=100> <img name=nether_netherrack.png^nether_netherrack_soil.png width=100>
3. Right click onto the Dirty Netherrack with a Nether mushroom head to add some spores
<item name=nether:shroom_head width=100> <img name=nether_netherrack.png^nether_netherrack_soil.png width=100>
4. Wait
5. Dig the Nether mushroom which grew after some time to make place for another one. After some time new spores need to be added (step 3).
<img name=riesenpilz_nether_shroom_side.png width=100>
<img name=nether_netherrack.png^nether_netherrack_soil.png width=100>
]]},
{"Blood Structures",
[[We can find blood structures on the ground and dig their nodes with the bare hand. They contain four kinds of nodes: Nether Blood Stem, Nether Blood, Nether Blood Head, and Nether Fruit.
<item name=nether:blood_stem width=100> <item name=nether:blood width=100> <item name=nether:apple width=100>
We can craft four Nether Blood Wood nodes with the stem.
<item name=nether:wood width=100>
The four red blood nodes can be cooked in a furnace and, except Nether Blood Wood, their blood can be extracted with a Nether Blood Extractor.
<my_h2><b>Nether Fruit</b></my_h2>
<item name=nether:apple width=100>
Eating a Nether Fruit decreases life but it might work against hunger and give us blood:
<item name=nether:blood_extracted width=100>
If we eat it at the right place inside a portal, we will teleport instead of getting blood.
If we drop it without holding the fast key, we can split it into its fruit and leaf:
<item name=nether:fruit_leaf width=100> <item name=nether:fruit_no_leaf width=100>
We can craft a fruit leave block out of 9 fruit leaves
The fruit can be used to craft a nether pearl.
<item name=nether:fruit_leaves width=100>
A fruit leaves block
<my_h2><b>Cultivating Blood Structures</b></my_h2>
If we dig a Nether vine we get a Nether Blood Child. If this sapling is put in a dark place (light level <= 3) on top of a Nether Blood Head node, it grows into a new blood structure after some time.
<img name=nether_sapling.png width=100>
<img name=nether_blood.png^nether_blood_side.png width=100>
]]},
{"Tools",
[[We can craft five kinds of tools in the nether, which (except the Nether Mushroom Pickaxe) require sticks to be crafted. To obtain Nether Sticks we can use the Nether Blood Extractor.
<my_h2><b>Nether Mushroom Pickaxe</b></my_h2>
<item name=nether:pick_mushroom width=100>
Strength: 1
This pickaxe needs mushroom stems and heads to be crafted.
<my_h2><b>Nether Wood Pickaxe</b></my_h2>
<item name=nether:pick_wood width=100>
Strength: 2
This pickaxe can be crafted with Cooked Nether Blood Wood.
<my_h2><b>Netherrack Tools</b></my_h2>
<item name=nether:axe_netherrack width=100> <item name=nether:shovel_netherrack width=100> <item name=nether:sword_netherrack width=100> <item name=nether:pick_netherrack width=100>
Strength: 3
The red Netherrack tools can be crafted with usual Netherrack.
<my_h2><b>Faster Tools</b></my_h2>
<item name=nether:axe_netherrack_blue width=100> <item name=nether:shovel_netherrack_blue width=100> <item name=nether:sword_netherrack_blue width=100> <item name=nether:pick_netherrack_blue width=100>
Strength: 3
The blue Netherrack tools can be crafted with Blue Netherrack.
<item name=nether:axe_white width=100> <item name=nether:shovel_white width=100> <item name=nether:sword_white width=100> <item name=nether:pick_white width=100>
Strength: 3
The Siwtonic tools can be crafted with the Siwtonic block.
]]},
{"Cooking",
[[To get a furnace we need to dig at least 8 Netherrack Bricks. They can be found at pyramid-like constructions and require at least a strength 1 nether pickaxe to be dug.
To begin cooking things, we can use a mushroom or fruit to power a furnace. After that it is recommended to use cooked blood nodes.
<my_h2><b>Craft Recipe</b></my_h2>
To craft the furnace, we can use the netherrack bricks like cobble:
<item name=nether:netherrack_brick width=100> <item name=nether:netherrack_brick width=100> <item name=nether:netherrack_brick width=100>
<item name=nether:netherrack_brick width=100> <img name=nether_transparent.png width=100> <item name=nether:netherrack_brick width=100>
<item name=nether:netherrack_brick width=100> <item name=nether:netherrack_brick width=100> <item name=nether:netherrack_brick width=100>
<my_h2><b>Cooking Outputs</b></my_h2>
Some nether items can be cooked, for example the Blood Structure's nodes.
<item name=nether:blood_stem_cooked width=100> <item name=nether:blood_cooked width=100> <item name=nether:blood_top_cooked width=100> <item name=nether:wood_cooked width=100>
Other cookable items are Blood and an item to get a Nether Pearl.
<item name=nether:hotbed width=100> <item name=nether:pearl width=100>
]]},
{"Nether Blood Extractor",
[[With this extractor we can separate Blood from the Blood Structure's nodes. An alternative way to get Blood is to eat Nether Fruits. The Nether Blood Extractor enables us to obtain a Nether Blood Stem Extracted, which we can craft to (empty) Nether Wood and then to Nether Sticks.
<my_h2><b>Craft Recipe</b></my_h2>
We can craft the Nether Blood Extractor as follows:
<item name=nether:netherrack_brick width=100> <item name=nether:blood_top_cooked width=100> <item name=nether:netherrack_brick width=100>
<item name=nether:blood_cooked width=100> <item name=nether:shroom_stem width=100> <item name=nether:blood_cooked width=100> <img name=nether_transparent.png width=100> <item name=nether:extractor width=100>
<item name=nether:netherrack_brick width=100> <item name=nether:blood_stem_cooked width=100> <item name=nether:netherrack_brick width=100>
<my_h2><b>Usage</b></my_h2>
We can feed the extractor with Blood to make it separate Blood from neighbouring nodes:
1. Place the Nether Blood Extractor somewhere
2. Place four or fewer Blood Structure's nodes next to it. Example viewed from the top:
<img name=nether_transparent.png width=100> <img name=nether_blood_stem_top.png width=100> <img name=nether_transparent.png width=100>
<img name=nether_blood.png width=100> <img name=nether_blood_extractor.png width=100> <img name=nether_blood.png width=100>
<img name=nether_transparent.png width=100> <img name=nether_blood.png width=100> <img name=nether_transparent.png width=100>
3. Right click the extractor with Blood to power it
<img name=nether_transparent.png width=100> <img name=nether_blood_stem_top_empty.png width=100> <img name=nether_transparent.png width=100>
<img name=nether_blood_empty.png width=100> <img name=nether_blood_extractor.png width=100> <img name=nether_blood_empty.png width=100>
<img name=nether_transparent.png width=100> <img name=nether_blood_empty.png width=100> <img name=nether_transparent.png width=100>
4. Take the new extracted blood and dig the extracted nodes
]]},
{"Ores and Bricks",
[[Digging ores requires a pickaxe from the nether of a sufficient strength. Pickaxes from the overworld do not work in general.
<my_h2><b>Strength 1</b></my_h2>
<item name=glow:stone width=100>
The Glowing stone can be dug with pickaxes from the overworld or a pickaxe from the nether with a strenght of least one. We can find it on the nether's and nether forest's ceiling and use it for lighting.
<my_h2><b>Strength 2</b></my_h2>
<item name=nether:netherrack width=100> <item name=nether:netherrack_tiled width=100> <item name=nether:netherrack_black width=100>
The (red) Netherrack is generated like stone, Tiled Netherrack is generated like coal ore and the Black Netherrack is generated like gravel.
<my_h2><b>Strength 3</b></my_h2>
<item name=nether:netherrack_blue width=100> <item name=nether:white width=100>
The Blue Netherrack is generated like diamond ore and the Siwtonic block is generated like mese blocks.
<my_h2><b>Bricks</b></my_h2>
There are three types of Bricks: red, Blue, and Black Netherrack Brick. We can craft them from the corresponding Netherrack nodes and additionally, the (red) Netherrack Brick is generated in pyramid-like structures in the nether. In comparison to the Netherrack nodes, all three Bricks can be dug with a pickaxe with strength 1.
<item name=nether:netherrack_brick width=100> <item name=nether:netherrack_brick_blue width=100> <item name=nether:netherrack_brick_black width=100>
]]},
{"Nether Vines",
[[Nether vines are at the ceiling of the nether and can be dug by hand. They drop Nether Blood Child nodes, from which we can grow Blood Structures. By feeding Blood to a Nether vine with air beneath it, it grows one node.
<item name=nether:vine width=100>
]]},
{"Portals",
[[This nether mod supports two types of portals: the well-known Minecraft-like one made of Obsidian, and a portal which is specific to this mod. The Obsidian portal allows us to reach the nether from the overworld, but it is one-way and kills us.
<my_h2><b>Build Instructions</b></my_h2>
A nether portal requires the following nodes:
<item name=nether:wood_empty width=100> <item name=nether:netherrack_black width=100> <item name=nether:netherrack_brick_blue width=100> <item name=nether:netherrack width=100> <item name=nether:blood_cooked width=100> <item name=nether:apple width=100> <item name=nether:white width=100>
* 25 (empty) Nether Wood (height 5-6)
* 16 Black Netherrack (height 1)
* 12 Blue Netherrack Bricks (height 2-4)
* 8 (red) Netherrack (height 1)
* 8 Cooked Nether Blood (height 5)
* 4 Nether Fruits (height 4)
* 2 Siwtonic blocks (height 1 and 5)
The heights in parenthesis correspond to the relative vertical positions of the nodes. When built, the portal should look approximately like this one:
<img name=nether_teleporter.png width=600>
<my_h2><b>Usage</b></my_h2>
Before using the portal the first time, we may want to fill our inventory with enough items so that we can build a second portal on the overworld to get back.
We can activate the portal as follows:
1. Stand in the middle on the Siwtonic block
2. Eat a Nether Fruit. If the portal was built correctly, we can hear a special sound and are teleported to the overworld.
If two portals in the nether and overworld have the same X and Z coordinates, they teleport us to the centre, i.e. onto the Siwtonic block, of the opposite portal when eating a Nether Fruit.
]]},
{"Pearls",
[[The nether pearl can be used to teleport by throwing it.
<my_h2><b>Craft Recipe</b></my_h2>
First, we need to craft two Nether Mushroom Heads and a Nether Fruit Without Leaf together as follows:
<item name=nether:shroom_head width=100>
<item name=nether:fruit_no_leaf width=100>
<item name=nether:shroom_head width=100>
This gives us the Nether Fruit in Mushroom (FIM), which we can cook in a furnace to obtain a Nether Pearl.
<item name=nether:fim width=100> <item name=nether:pearl width=100>
]]},
{"Nether Forest",
[[The nether forest is generated in caves above the nether and contains decorative plants.
<my_h2><b>Grass and Flower</b></my_h2>
<item name=nether:grass_big width=100> <item name=nether:grass_middle width=100> <item name=nether:grass_small width=100>
We can craft the Nether Grass item to another grass item, which can be cooked to get Dried Nether Grass. We can then craft this dried grass to paper.
<item name=nether:glowflower width=100>
The Glowing Flower can be used for lighting and decoration.
<my_h2><b>Nether Tree</b></my_h2>
<item name=nether:tree width=100>
Nether trunks can be found at Nether Trees and be crafted into Nether Wood Blocks via Nether Wood Planks. Furthermore, the Nether Tree Saplings grow even in the overworld if they have Nether Dirt beneath them.
]]}
}
-- The guide formspecs
local guide_forms = {}
-- Convert the guide content to formspecs
for n,data in ipairs(guide_infos) do
local title, html_content = data[1], data[2]
--~ local html_text = "<global background=#242424 size=24><tag name=my_h1 size=35>" ..
local html_text = "<global size=24><tag name=my_h1 size=35>" ..
"<tag name=my_h2 size=30>" ..
"<my_h1><b><center>" .. title .. "</b></center></my_h1>\n" ..
html_content
local spec_width = 16
local spec_height = 16
local html_padding = 0.5
local form = ("formspec_version[4]size[%g,%g;]" ..
"hypertext[%g,%g;%g,%g;html;%s]button[%g,%g;2,0.8;quit;Back]"
):format(
spec_width, spec_height,
html_padding, html_padding,
spec_width - 2 * html_padding, spec_height - 1 - 2 * html_padding,
minetest.formspec_escape(html_text),
0.5 * spec_width - 1, spec_height - 1)
guide_forms[n] = {title, form}
end
local title_to_index = {}
for n, i in ipairs(guide_forms) do
title_to_index[i[1]] = n
end
-- Create the contents formspec
guide_forms.contents = "formspec_version[4]size[6," .. (#guide_infos) + 2 ..
";]label[2,0.8;Contents:]"
for i, data in ipairs(guide_forms) do
local desc = data[1]
local y = i + 0.5 + 0.1
guide_forms.contents = guide_forms.contents ..
"button[0.5," .. y .. ";5,0.8;name;" .. desc .. "]"
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname == "nether_guide_contents" then
local fname = fields.name
local pname = player:get_player_name()
if fname
and pname then
minetest.show_formspec(pname, "nether_guide",
guide_forms[title_to_index[fname]][2])
end
elseif formname == "nether_guide" then
local fname = fields.quit
local pname = player:get_player_name()
if fname
and pname then
minetest.show_formspec(pname, "nether_guide_contents",
guide_forms["contents"])
end
end
end)
minetest.register_chatcommand("nether_help", {
params = "",
description = "Shows a nether guide",
func = function(name)
local player = minetest.get_player_by_name(name)
if not player then
return false, "Something went wrong."
end
if not nether.overworld_help and player:get_pos().y > nether.v.nether_start then
return false, "Usually you don't neet this guide here. " ..
"You can view it in the nether."
end
minetest.chat_send_player(name, "Showing guide...")
-- Show the Contents (overview) page
minetest.show_formspec(name, "nether_guide_contents",
guide_forms["contents"])
return true
end
})

File diff suppressed because it is too large Load Diff

13
nether/init_emerge.lua Normal file
View File

@ -0,0 +1,13 @@
-- This is run in mapgen env (see register_mapgen_script)
nether = {}
nether.env_type = "ssm_mapgen"
nether.path = minetest.get_modpath("nether")
local path = nether.path
dofile(path .. "/common.lua")
dofile(path .. "/grow_structures.lua")
dofile(path .. "/mapgen.lua")

1034
nether/items.lua Normal file

File diff suppressed because it is too large Load Diff

519
nether/mapgen.lua Normal file
View File

@ -0,0 +1,519 @@
local path = nether.path
local in_mapgen_env = nether.env_type == "ssm_mapgen"
-- vars
local v = nether.v
local nether_middle = v.nether_middle
local f_bottom_scale = v.f_bottom_scale
local f_h_min = v.f_h_min
local f_h_max = v.f_h_max
local tree_rarity = v.tree_rarity
local glowflower_rarity = v.glowflower_rarity
local grass_rarity = v.grass_rarity
local mushroom_rarity = v.mushroom_rarity
local nether_start = v.nether_start
local NETHER_HEIGHT = v.NETHER_HEIGHT
local NETHER_RANDOM = v.NETHER_RANDOM
local GLOWSTONE_FREQ_ROOF = v.GLOWSTONE_FREQ_ROOF
local LAVA_FREQ = v.LAVA_FREQ
local nether_structure_freq = v.nether_structure_freq
local NETHER_SHROOM_FREQ = v.NETHER_SHROOM_FREQ
local NETHER_BOTTOM = v.NETHER_BOTTOM
local nether_buildings = v.nether_buildings
local nether_weird_noise = dofile(path .. "/weird_mapgen_noise.lua")
-- Weierstrass function stuff from https://github.com/slemonide/gen
local get_ws_list
do
local SIZE = 1000
local ssize = math.ceil(math.abs(SIZE))
local function do_ws_func(depth, a, x)
local n = math.pi * x / (16 * SIZE)
local y = 0
for k=1,depth do
y = y + math.sin(k^a * n) / k^a
end
return SIZE * y / math.pi
end
local chunksize = minetest.settings:get"chunksize" or 5
local ws_lists = {}
get_ws_list = function(a,x)
ws_lists[a] = ws_lists[a] or {}
local v = ws_lists[a][x]
if v then
return v
end
v = {}
for x=x,x + (chunksize*16 - 1) do
local y = do_ws_func(ssize, a, x)
v[x] = y
end
ws_lists[a][x] = v
return v
end
end
local function dif(z1, z2)
return math.abs(z1-z2)
end
local function pymg(x1, x2, z1, z2)
return math.max(dif(x1, x2), dif(z1, z2))
end
-- Generated variables
--~ local NETHER_ROOF_ABS = (nether_middle - NETHER_RANDOM)
local f_yscale_top = (f_h_max-f_h_min)/2
local f_yscale_bottom = f_yscale_top/2
--HADES_THRONE_STARTPOS_ABS = {x=HADES_THRONE_STARTPOS.x, y=(NETHER_BOTTOM +
--HADES_THRONE_STARTPOS.y), z=HADES_THRONE_STARTPOS.z}
--LAVA_Y = (NETHER_BOTTOM + LAVA_HEIGHT)
--HADES_THRONE_ABS = {}
--HADES_THRONE_ENDPOS_ABS = {}
--HADES_THRONE_GENERATED = minetest.get_worldpath() .. "/netherhadesthrone.txt"
--NETHER_SPAWNPOS_ABS = {x=NETHER_SPAWNPOS.x, y=(NETHER_BOTTOM +
--NETHER_SPAWNPOS.y), z=NETHER_SPAWNPOS.z}
--[[for i,v in ipairs(HADES_THRONE) do
v.pos.x = v.pos.x + HADES_THRONE_STARTPOS_ABS.x
v.pos.y = v.pos.y + HADES_THRONE_STARTPOS_ABS.y
v.pos.z = v.pos.z + HADES_THRONE_STARTPOS_ABS.z
HADES_THRONE_ABS[i] = v
end
local htx = 0
local hty = 0
local htz = 0
for i,v in ipairs(HADES_THRONE_ABS) do
if v.pos.x > htx then
htx = v.pos.x
end
if v.pos.y > hty then
hty = v.pos.y
end
if v.pos.z > htz then
htz = v.pos.z
end
end
HADES_THRONE_ENDPOS_ABS = {x=htx, y=hty, z=htz}]]
local c, nether_tree_nodes, contents_defined
local function define_contents()
if not contents_defined then
c, nether_tree_nodes = nether.query_contents()
contents_defined = true
end
end
local pr
local function return_nether_ore(id, glowstone)
if glowstone
and pr:next(0,GLOWSTONE_FREQ_ROOF) == 1 then
return c.glowstone
end
if id == c.coal then
return c.netherrack_tiled
end
if id == c.gravel then
return c.netherrack_black
end
if id == c.diamond then
return c.netherrack_blue
end
if id == c.mese then
return c.white
end
return c.netherrack
end
local f_perlins = {}
-- abs(v) < 1-(persistance^octaves))/(1-persistance) = amp
--local perlin1 = minetest.get_perlin(13,3, 0.5, 50) --Get map specific perlin
-- local perlin2 = minetest.get_perlin(133,3, 0.5, 10)
-- local perlin3 = minetest.get_perlin(112,3, 0.5, 5)
local tmp = f_yscale_top*4
local tmp2 = tmp/f_bottom_scale
local perlins = {
{ -- amp 1.75
seed = 13,
octaves = 3,
persist = 0.5,
spread = {x=50, y=50, z=50},
scale = 1,
offset = 0,
},
{-- amp 1.75
seed = 133,
octaves = 3,
persist = 0.5,
spread = {x=10, y=10, z=10},
scale = 1,
offset = 0,
},
{-- amp 1.75
seed = 112,
octaves = 3,
persist = 0.5,
spread = {x=5, y=5, z=5},
scale = 1,
offset = 0,
},
--[[forest_bottom = {
seed = 11,
octaves = 3,
persist = 0.8,
spread = {x=tmp2, y=tmp2, z=tmp2},
scale = 1,
offset = 0,
},]]
forest_top = {-- amp 2.44
seed = 21,
octaves = 3,
persist = 0.8,
spread = {x=tmp, y=tmp, z=tmp},
scale = 1,
offset = 0,
},
}
-- buffers, see https://forum.minetest.net/viewtopic.php?f=18&t=16043
local pelin_maps
local pmap1 = {}
local pmap2 = {}
local pmap3 = {}
local pmap_f_top = {}
local data = {}
local structures_enabled = true
local vine_maxlength = math.floor(NETHER_HEIGHT/4+0.5)
-- Create the Nether
local function on_generated(minp, maxp, seed)
--avoid big map generation
if not (maxp.y >= NETHER_BOTTOM-100 and minp.y <= nether_start) then
return
end
local t1 = minetest.get_us_time()
nether:inform("generates at: x=["..minp.x.."; "..maxp.x.."]; y=[" ..
minp.y.."; "..maxp.y.."]; z=["..minp.z.."; "..maxp.z.."]", 2)
define_contents()
local buildings = 0
if maxp.y <= NETHER_BOTTOM then
buildings = 1
elseif minp.y <= nether_buildings then
buildings = 2
end
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
vm:get_data(data)
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
pr = PseudoRandom(seed+33)
local tab,num = {},1
local trees,num_trees = {},1
--local perlin1 = minetest.get_perlin(13,3, 0.5, 50)
--local perlin2 = minetest.get_perlin(133,3, 0.5, 10)
--local perlin3 = minetest.get_perlin(112,3, 0.5, 5)
local side_length = maxp.x - minp.x + 1
local map_lengths_xyz = {x=side_length, y=side_length, z=side_length}
if not pelin_maps then
pelin_maps = {
a = minetest.get_perlin_map(perlins[1], map_lengths_xyz),
b = minetest.get_perlin_map(perlins[2], map_lengths_xyz),
c = minetest.get_perlin_map(perlins[3], map_lengths_xyz),
forest_top = minetest.get_perlin_map(perlins.forest_top,
map_lengths_xyz),
}
end
pelin_maps.a:get_2d_map_flat({x=minp.x, y=minp.z}, pmap1)
pelin_maps.b:get_2d_map_flat({x=minp.x, y=minp.z}, pmap2)
pelin_maps.c:get_2d_map_flat({x=minp.x, y=minp.z}, pmap3)
local forest_possible = maxp.y > f_h_min and minp.y < f_h_max
--local pmap_f_bottom = minetest.get_perlin_map(perlins.forest_bottom,
-- map_lengths_xyz):get_2d_map_flat({x=minp.x, y=minp.z})
local perlin_f_bottom, strassx, strassz
if forest_possible then
perlin_f_bottom = minetest.get_perlin(11, 3, 0.8, tmp2)
pelin_maps.forest_top:get_2d_map_flat({x=minp.x, y=minp.z}, pmap_f_top)
strassx = get_ws_list(2, minp.x)
strassz = get_ws_list(2, minp.z)
end
local num2, tab2
if buildings >= 1 then
num2 = 1
tab2 = nether_weird_noise({x=minp.x, y=nether_buildings-79, z=minp.z},
pymg, 200, 8, 10, side_length-1)
end
local count = 0
for z=minp.z, maxp.z do
for x=minp.x, maxp.x do
count = count+1
local test = pmap1[count]+1
local test2 = pmap2[count]
local test3 = math.abs(pmap3[count])
local t = math.floor(test*3+0.5)
local h
if test2 < 0 then
h = math.floor(test2*3+0.5)-1
else
h = 3+t+pr:next(0,NETHER_RANDOM)
end
local generate_vine = false
if test3 >= 0.72+pr:next(0,NETHER_RANDOM)/10
and pr:next(0,NETHER_RANDOM) == 1 then
generate_vine = true
end
local bottom = NETHER_BOTTOM+h
local top = nether_middle-pr:next(0,NETHER_RANDOM)+t
local py_h = 0
local difn, noisp, py_h_g
if buildings >= 1 then
py_h = tab2[num2].y
num2 = num2+1
difn = nether_buildings-py_h
if difn == 5 then
noisp = 1
elseif difn < 5 then
noisp = 2
end
py_h_g = nether_buildings-7
end
local vi = area:index(x, minp.y, z)
if buildings == 1
and noisp then
if noisp == 1 then
for _ = 1,side_length do
data[vi] = c.netherrack_brick
vi = vi + area.ystride
end
else
for _ = 1,side_length do
data[vi] = c.lava
vi = vi + area.ystride
end
end
else
local r_structure = pr:next(1,nether_structure_freq)
local r_shroom = pr:next(1,NETHER_SHROOM_FREQ)
local r_glowstone = pr:next(0,GLOWSTONE_FREQ_ROOF)
local r_vine_length = pr:next(1,vine_maxlength)
local f_bottom, f_top, is_forest, f_h_dirt
if forest_possible then
local p = {x=math.floor(x/f_bottom_scale),
z=math.floor(z/f_bottom_scale)}
local pstr = p.x.." "..p.z
if not f_perlins[pstr] then
f_perlins[pstr] = math.floor(f_h_min + (math.abs(
perlin_f_bottom:get_2d{x=p.x, y=p.z} + 1))
* f_yscale_bottom + 0.5)
end
local top_noise = pmap_f_top[count]+1
if top_noise < 0 then
top_noise = -top_noise/10
--nether:inform("ERROR: (perlin noise) "..
-- pmap_f_top[count].." is not inside [-1; 1]", 1)
end
f_top = math.floor(f_h_max - top_noise*f_yscale_top + 0.5)
f_bottom = f_perlins[pstr]+pr:next(0,f_bottom_scale-1)
is_forest = f_bottom < f_top
f_h_dirt = f_bottom-pr:next(0,1)
end
for y=minp.y, maxp.y do
local d_p_addp = data[vi]
--if py_h >= maxp.y-4 then
if y <= py_h
and noisp then
if noisp == 1 then
data[vi] = c.netherrack_brick
elseif noisp == 2 then
if y == py_h then
data[vi] = c.netherrack_brick
elseif y == py_h_g
and pr:next(1,3) <= 2 then
data[vi] = c.netherrack
elseif y <= py_h_g then
data[vi] = c.lava
else
data[vi] = c.air
end
end
elseif d_p_addp ~= c.air then
if is_forest
and y == f_bottom then
data[vi] = c.nether_dirt_top
elseif is_forest
and y < f_bottom
and y >= f_h_dirt then
data[vi] = c.nether_dirt
elseif is_forest
and y == f_h_dirt-1 then
data[vi] = c.nether_dirt_bottom
elseif is_forest
and y == f_h_dirt+1 then
if pr:next(1,tree_rarity) == 1 then
trees[num_trees] = {x=x, y=y, z=z}
num_trees = num_trees+1
elseif pr:next(1,mushroom_rarity) == 1 then
data[vi] = c.nether_shroom
elseif pr:next(1,glowflower_rarity) == 1 then
data[vi] = c.glowflower
elseif pr:next(1,grass_rarity) == 1 then
data[vi] = c.nether_grass[pr:next(1,3)]
else
data[vi] = c.air
end
elseif is_forest
and y > f_bottom
and y < f_top then
if not nether_tree_nodes[d_p_addp] then
data[vi] = c.air
end
elseif is_forest
and y == f_top then
local sel = math.floor(strassx[x]+strassz[z]+0.5)%10
if sel <= 5 then
data[vi] = return_nether_ore(d_p_addp, true)
elseif sel == 6 then
data[vi] = c.netherrack_black
elseif sel == 7 then
data[vi] = c.glowstone
else
data[vi] = c.air
end
elseif y <= NETHER_BOTTOM then
if y <= bottom then
data[vi] = return_nether_ore(d_p_addp, true)
else
data[vi] = c.lava
end
elseif r_structure == 1
and y == bottom then
tab[num] = {x=x, y=y-1, z=z}
num = num+1
elseif y <= bottom then
if pr:next(1,LAVA_FREQ) == 1 then
data[vi] = c.lava
else
data[vi] = return_nether_ore(d_p_addp, false)
end
elseif r_shroom == 1
and r_structure ~= 1
and y == bottom+1 then
data[vi] = c.nether_shroom
elseif (y == top and r_glowstone == 1) then
data[vi] = c.glowstone
elseif y >= top then
data[vi] = return_nether_ore(d_p_addp, true)
elseif y <= top-1
and generate_vine
and y >= top-r_vine_length then
data[vi] = c.nether_vine
else
data[vi] = c.air
end
end
vi = vi + area.ystride
end
end
end
end
nether:inform("most stuff set", 2, t1)
local t2 = minetest.get_us_time()
local bl_cnt = 0
local tr_cnt = 0
local tr_snd_cnt = 0
if structures_enabled then -- Blood netherstructures
bl_cnt = #tab
for i = 1, #tab do
nether.grow_netherstructure_into(area, data, tab[i], true)
end
end
if bl_cnt > 0 then
nether:inform(bl_cnt .. " blood structures set", 2, t2)
end
t2 = minetest.get_us_time()
vm:set_data(data)
-- vm:set_lighting(12)
-- vm:calc_lighting()
-- vm:update_liquids()
if not in_mapgen_env then
vm:write_to_map(false)
end
nether:inform("data written", 2, t2)
t2 = minetest.get_us_time()
if forest_possible then -- Forest trees
if in_mapgen_env then
-- Trees can get too big (>16 nodes in one direction) for usual
-- overgeneration onion layer. nether.grow_tree will make new vmanips
-- to emerge blank (= ignore-filled) blocks to overcome this. But the
-- main server thread needs to do this.
tr_snd_cnt = #trees
local trees_hashed = {}
for i = 1, #trees do
trees_hashed[i] = minetest.hash_node_position(trees[i])
end
assert(minetest.save_gen_notify("nether:please_grow_trees", trees_hashed))
else
tr_cnt = #trees
for i = 1, #trees do
nether.grow_tree(trees[i], true)
end
end
end
if tr_cnt + tr_snd_cnt > 0 then
nether:inform(string.format("%s trees set, %s trees sent",
tr_cnt, tr_snd_cnt), 2, t2)
end
if in_mapgen_env then
assert(minetest.save_gen_notify("nether:please_fix_light", {minp, maxp}))
else
t2 = minetest.get_us_time()
minetest.fix_light(minp, maxp)
nether:inform("light fixed", 2, t2)
end
nether:inform("done", 1, t1)
end
if in_mapgen_env then
minetest.register_on_generated(function(_, minp, maxp, blockseed)
return on_generated(minp, maxp, blockseed)
end)
else
minetest.register_on_generated(on_generated)
end

3
nether/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = nether
depends = default,glow,riesenpilz
optional_depends = creative,fence_registration,function_delayer,stairs,watershed

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

190
nether/pearl.lua Normal file
View File

@ -0,0 +1,190 @@
local function throw_pearl(item, player)
local playerpos = player:get_pos()
playerpos.y = playerpos.y+1.625
local obj = minetest.add_entity(playerpos, "nether:pearl_entity")
local dir = player:get_look_dir()
obj:set_velocity(vector.multiply(dir, 30))
obj:set_acceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3})
local pname = player:get_player_name()
obj:get_luaentity().player = pname
if not minetest.is_creative_enabled(pname) then
item:take_item()
return item
end
end
local function get_node(pos)
local name = minetest.get_node(pos).name
if name ~= "ignore" then
return name
end
minetest.get_voxel_manip():read_from_map(pos, pos)
name = minetest.get_node_or_nil(pos)
if not name then
return
end
return name.name
end
local softs = {}
local function is_soft(pos)
local name = get_node(pos)
if not name then
return false
end
local is_soft = softs[name]
if is_soft ~= nil then
return is_soft
end
if not minetest.registered_nodes[name] then
softs[name] = false
return false
end
is_soft = minetest.registered_nodes[name].walkable == false
softs[name] = is_soft
return is_soft
end
-- teleports the player there if there's free space
local function teleport_player(pos, player)
if not is_soft(pos) then
return false
end
if not is_soft({x=pos.x, y=pos.y+1, z=pos.z})
and not is_soft({x=pos.x, y=pos.y-1, z=pos.z}) then
return false
end
pos.y = pos.y+0.05
player:move_to(pos)
return true
end
--[[
local dg_ps = {}
local function forceload(pos)
dg_ps[#dg_ps+1] = pos
minetest.forceload_block(pos)
minetest.after(5, function(pos)
minetest.forceload_free_block(pos)
for i,p in pairs(dg_ps) do
if vector.equals(p, pos) then
dg_ps[i] = nil
return
end
end
end, pos)
end
minetest.register_on_shutdown(function()
for _,p in pairs(dg_ps) do
minetest.forceload_free_block(p)
end
end)--]]
minetest.register_entity("nether:pearl_entity", {
collisionbox = {0,0,0,0,0,0}, --not pointable
visual_size = {x=0.1, y=0.1},
physical = false, -- Collides with things
textures = {"nether_pearl.png"},
on_activate = function(self, staticdata)
if not staticdata
or staticdata == "" then
return
end
local tmp = minetest.deserialize(staticdata)
if not tmp then
minetest.log("error", "[nether] pearl: invalid staticdata ")
return
end
self.player = tmp.player
end,
get_staticdata = function(self)
--forceload(vector.round(self.object:get_pos()))
return minetest.serialize({
player = self.player,
})
end,
timer = 0,
on_step = function(self, dtime)
self.timer = self.timer+dtime
--[[
local delay = self.delay
if delay < 0.1 then
self.delay = delay+dtime
return
end
self.delay = 0--]]
if self.timer > 20 then
self.object:remove()
return
end
local pos = self.object:get_pos()
local rpos = vector.round(pos)
local lastpos = self.lastpos
if not lastpos then
self.lastpos = vector.new(rpos)
return
end
if lastpos.x
and vector.equals(vector.round(lastpos), rpos) then
return
end
local player = self.player
if not player then
minetest.log("error", "[nether] pearl: missing playername")
self.object:remove()
return
end
player = minetest.get_player_by_name(player)
if not player then
minetest.log("error", "[nether] pearl: missing player")
self.object:remove()
return
end
if not get_node(rpos) then
minetest.log("error", "[nether] pearl: missing node")
self.object:remove()
return
end
self.lastpos = vector.new(pos)
local free, p = minetest.line_of_sight(lastpos, pos)
if free then
return
end
if is_soft(p) then
return
end
self.object:remove()
minetest.after(0, function(p) --minetest.after is used that the sound is played after the teleportation
minetest.sound_play("nether_pearl", {pos=p, max_hear_distance=10})
end, p)
p.y = p.y+1
if teleport_player(vector.new(p), player) then
return
end
p.y = p.y-2
for i = -1,1,2 do
for _,j in pairs({{i, 0}, {0, i}}) do
if teleport_player({x=p.x+j[1], y=p.y, z=p.z+j[2]}, player) then
return
end
end
end
for i = -1,1,2 do
for j = -1,1,2 do
if teleport_player({x=p.x+j, y=p.y, z=p.z+i}, player) then
return
end
end
end
end
})
minetest.override_item("nether:pearl", {on_use = throw_pearl})

828
nether/portal.lua Normal file
View File

@ -0,0 +1,828 @@
--code copied from Pilzadam's nether mod and edited
local nether_start = nether.v.nether_start
local nether_bottom = nether.v.nether_bottom
local nether_buildings = nether.v.nether_buildings
-- kills the player if he uses PilzAdam portal
local portal_target = nether_buildings+1
local damage_enabled = minetest.settings:get_bool"enable_damage"
local mclike_portal = false
local abm_allowed
minetest.after(5, function()
abm_allowed = true
end)
local save_path = minetest.get_worldpath() .. "/nether_players"
local players_trapped_in_nether = {}
-- Load the list of players which are trapped in the nether
-- (or would be trapped if nether.trap_players was true)
do
local file = io.open(save_path, "r")
if file then
local contents = file:read"*all"
io.close(file)
if contents then
local playernames = string.split(contents, " ")
for i = 1,#playernames do
players_trapped_in_nether[playernames[i]] = true
end
end
end
end
local function save_nether_players()
local playernames,n = {},1
for name in pairs(players_trapped_in_nether) do
playernames[n] = name
n = n+1
end
local f = io.open(save_path, "w")
assert(f, "Could not open nether_players file for writing.")
f:write(table.concat(playernames, " "))
io.close(f)
end
-- Nether aware mods will need to know if a player is in the nether.
function nether.is_player_in_nether(player)
local pos = player:get_pos()
return (pos.y < nether_start) and (pos.y >= nether_bottom)
end
-- For testing nether trap state tracking.
function nether.is_player_trapped_in_nether(player)
return players_trapped_in_nether[player:get_player_name()]
end
local update_background
if nether.trap_players then
function update_background(player, down)
if down then
player:set_sky({r=15, g=0, b=0}, "plain")
else
player:set_sky(nil, "regular")
end
end
else
function update_background()end
end
-- Nether aware mods may have other means of moving players between the Nether
-- and Overworld, and if so, they should tell us about it so we can keep track
-- of the player state.
function nether.external_nether_teleport(player, pos)
if not nether.trap_players then
player:set_pos(pos)
return
end
local destination_in_nether = (pos.y < nether_start) and (pos.y >= nether_bottom)
update_background(player, destination_in_nether)
local pname = player:get_player_name()
players_trapped_in_nether[pname] = destination_in_nether or nil
player:set_pos(pos)
end
-- Has the player dug their way out of the nether?
-- Has nether.trap_players been disabled?
function nether.registry_update(player)
local pos = player:get_pos()
local in_nether = (pos.y < nether_start) and (pos.y >= nether_bottom)
local pname = player:get_player_name()
if nether.trap_players then
players_trapped_in_nether[pname] = in_nether or nil
update_background(player, in_nether)
elseif players_trapped_in_nether[pname] then
players_trapped_in_nether[pname] = nil
update_background(player, false)
end
end
-- returns nodename if area is generated, else calls generation function
local function generated_or_generate(pos)
local node = minetest.get_node_or_nil(pos)
if node then
return node.name
end
minetest.get_voxel_manip():read_from_map(pos, pos)
node = minetest.get_node_or_nil(pos)
if not node then
minetest.emerge_area(vector.subtract(pos, 80), vector.add(pos, 80))
return false
end
return node.name
end
-- where the player appears after dying
local function get_player_died_target(player)
local target = vector.add(player:get_pos(),
{x=math.random(-100,100), y=0, z=math.random(-100,100)})
target.y = portal_target + math.random(4)
return target
end
-- used for obsidian portal
local function obsidian_teleport(player, pname, target)
minetest.chat_send_player(pname, "For some reason you arrived here. Type " ..
"/nether_help to find out things like craft recipes.")
players_trapped_in_nether[pname] = true
save_nether_players()
update_background(player, true)
if target then
player:set_pos(target)
else
player:set_hp(0)
end
end
-- teleports players to nether or helps it
local function player_to_nether(player, pos)
local pname = player:get_player_name()
players_trapped_in_nether[pname] = true
save_nether_players()
update_background(player, true)
if pos then
player:set_pos(pos)
return
end
minetest.chat_send_player(pname, "For some reason you arrived here. " ..
"Type /nether_help to find out things like craft recipes.")
if nether.trap_players then
player:set_hp(0)
end
if not damage_enabled or not nether.trap_players then
player:set_pos(get_player_died_target(player))
end
end
local function player_from_nether(player, pos)
local pname = player:get_player_name()
if players_trapped_in_nether[pname] then
players_trapped_in_nether[pname] = nil
save_nether_players()
end
update_background(player, false)
player:set_pos(pos)
end
local function player_exists(name)
local players = minetest.get_connected_players()
for i = 1,#players do
if players[i]:get_player_name() == name then
return true
end
end
return false
end
-- Chatcommands (edited) written by sss
minetest.register_chatcommand("to_hell", {
params = "[<player_name>]",
description = "Send someone to hell",
func = function(name, pname)
if not minetest.check_player_privs(name, {nether=true}) then
return false,
"You need the nether privilege to execute this chatcommand."
end
if not player_exists(pname) then
pname = name
end
local player = minetest.get_player_by_name(pname)
if not player then
return false, "Something went wrong."
end
minetest.chat_send_player(pname, "Go to hell !!!")
player_to_nether(player)
return true, pname.." is now in the nether."
end
})
minetest.register_chatcommand("from_hell", {
params = "[<player_name>]",
description = "Extract from hell",
func = function(name, pname)
if not minetest.check_player_privs(name, {nether=true}) then
return false,
"You need the nether priv to execute this chatcommand."
end
if not player_exists(pname) then
pname = name
end
local player = minetest.get_player_by_name(pname)
if not player then
return false, "Something went wrong."
end
minetest.chat_send_player(pname, "You are free now")
local pos = player:get_pos()
player_from_nether(player, {x=pos.x, y=100, z=pos.z})
return true, pname.." is now out of the nether."
end
})
-- Useful for debugging Nether player state tracking. Written by Deathwing777
minetest.register_chatcommand("in_hell", {
params = "[<player_name>]",
description = "Is the player in hell?",
func = function(name, pname)
if not minetest.check_player_privs(name, {nether=true}) then
return false,
"You need the nether priv to execute this chatcommand."
end
if not player_exists(pname) then
pname = name
end
local player = minetest.get_player_by_name(pname)
if not player then
return false, "Something went wrong."
end
local status = pname.." is in the "
if nether.is_player_in_nether(player) then
status = status.."NETHER!"
else
status = status.."OVERWORLD!"
end
return true, status
end
})
-- Useful for debugging Nether player state tracking. Written by Deathwing777
minetest.register_chatcommand("trapped_in_hell", {
params = "[<player_name>]",
description = "Is the player trapped in hell?",
func = function(name, pname)
if not minetest.check_player_privs(name, {nether=true}) then
return false,
"You need the nether priv to execute this chatcommand."
end
if not player_exists(pname) then
pname = name
end
local player = minetest.get_player_by_name(pname)
if not player then
return false, "Something went wrong."
end
local status = pname
if nether.is_player_trapped_in_nether(player) then
status = status.." is TRAPPED in nether!"
else
status = status.." is NOT trapped in nether!"
end
return true, status
end
})
-- Useful for debugging Nether player state tracking. Written by Deathwing777
minetest.register_chatcommand("update_hells_registry", {
params = "[<player_name>]",
description = "Update player state if they got to or from the nether in another way.",
func = function(name, pname)
if not minetest.check_player_privs(name, {nether=true}) then
return false,
"You need the nether priv to execute this chatcommand."
end
if not player_exists(pname) then
pname = name
end
local player = minetest.get_player_by_name(pname)
if not player then
return false, "Something went wrong."
end
nether.registry_update(player)
local status = pname
if nether.is_player_trapped_in_nether(player) then
status = status.." is TRAPPED in nether!"
else
status = status.." is NOT trapped in nether!"
end
return true, status
end
})
-- Disallow teleportation and change spawn positions if the nether traps players
if nether.trap_players then
-- randomly set player position when he/she dies in nether
minetest.register_on_respawnplayer(function(player)
local pname = player:get_player_name()
if not players_trapped_in_nether[pname] then
return
end
local target = get_player_died_target(player)
player:set_pos(target)
minetest.after(0, function(pname, target)
-- fixes respawn bug
local player = minetest.get_player_by_name(pname)
if player then
player:move_to(target)
end
end, pname, target)
return true
end)
-- override set_pos etc, to disallow player teleportion by e.g. travelnet
local function can_teleport(player, pos)
if not player:is_player() then
-- the same metatable is used for entities
return true
end
local pname = player:get_player_name()
local in_nether = players_trapped_in_nether[pname] == true
-- test if the target is valid
if pos.y < nether_start then
if in_nether then
return true
end
elseif not in_nether then
return true
end
-- test if the current position is valid
local current_pos = player:get_pos()
local now_in_nether = current_pos.y < nether_start
if now_in_nether ~= in_nether then
if in_nether then
minetest.log("action", "Player \"" .. pname ..
"\" has to be in the nether, teleporting it!")
update_background(player, true)
current_pos.y = portal_target
player:set_pos(current_pos)
else
minetest.log("action", "Player \"" .. pname ..
"\" must not be in the nether, teleporting it!")
update_background(player, false)
current_pos.y = 20
player:set_pos(current_pos)
end
return false
end
minetest.chat_send_player(pname,
"You can not simply teleport to or from the nether!")
minetest.log("action", "Player \"" .. pname ..
"\" attempted to teleport from or to the nether, ignoring.")
return false
end
local methods = {"set_pos", "move_to", "setpos", "moveto"}
local metatable_overridden
minetest.register_on_joinplayer(function(player)
-- set the background when the player joins
if player:get_pos().y < nether_start then
update_background(player, true)
end
-- overide set_pos etc. if not yet done
if metatable_overridden then
return
end
metatable_overridden = true
local mt = getmetatable(player)
for i = 1,#methods do
local methodname = methods[i]
local origfunc = mt[methodname]
mt[methodname] = function(...)
if can_teleport(...) then
origfunc(...)
end
end
end
end)
end
-- removes the violet stuff from the obsidian portal
local function remove_portal_essence(pos)
for z = -1,1 do
for y = -2,2 do
for x = -1,1 do
local p = {x=pos.x+x, y=pos.y+y, z=pos.z+z}
if minetest.get_node(p).name == "nether:portal" then
minetest.remove_node(p)
end
end
end
end
end
-- change parts of the particledefinition instead of recreating it every time
local particledef = {
amount = 32,
time = 4,
minvel = {x=0, y=1, z=0},
maxvel = {x=0, y=2, z=0},
minacc = {x=-0.5,y=-3,z=-0.3},
maxacc = {x=0.5,y=-0.4,z=0.3},
minexptime = 1,
maxexptime = 1,
minsize = 0.4,
maxsize = 3,
collisiondetection = true,
}
-- teleports player to neter (obsidian portal)
local function obsi_teleport_player(player, pos, target)
local pname = player:get_player_name()
if players_trapped_in_nether[pname] then
return
end
local objpos = player:get_pos()
objpos.y = objpos.y+0.1 -- Fix some glitches at -8000
if minetest.get_node(vector.round(objpos)).name ~= "nether:portal" then
return
end
local has_teleported
if (damage_enabled and nether.trap_players) then
obsidian_teleport(player, pname)
has_teleported = true
elseif not mclike_portal then
local target = vector.round(get_player_died_target(player))
if generated_or_generate(target) then
obsidian_teleport(player, pname, target)
has_teleported = true
end
end
if not has_teleported then
-- e.g. ungenerated area
return
end
remove_portal_essence(pos)
minetest.sound_play("nether_portal_usual", {to_player=pname, gain=1})
end
-- abm for particles of the obsidian portal essence and for teleporting
minetest.register_abm({
nodenames = {"nether:portal"},
interval = 1,
chance = 2,
catch_up = false,
action = function(pos, node)
if not abm_allowed then
return
end
particledef.minpos = {x=pos.x-0.25, y=pos.y-0.5, z=pos.z-0.25}
particledef.maxpos = {x=pos.x+0.25, y=pos.y+0.34, z=pos.z+0.25}
particledef.texture = "nether_portal_particle.png^[transform" ..
math.random(0, 7)
minetest.add_particlespawner(particledef)
for _,obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do
if obj:is_player() then
local meta = minetest.get_meta(pos)
local target = minetest.string_to_pos(meta:get_string("target"))
if target then
minetest.after(3, obsi_teleport_player, obj, pos, target)
end
end
end
end,
})
local function move_check(p1, max, dir)
local p = {x=p1.x, y=p1.y, z=p1.z}
local d = math.abs(max-p1[dir]) / (max-p1[dir])
while p[dir] ~= max do
p[dir] = p[dir] + d
if minetest.get_node(p).name ~= "default:obsidian" then
return false
end
end
return true
end
local function check_portal(p1, p2)
if p1.x ~= p2.x then
if not move_check(p1, p2.x, "x") then
return false
end
if not move_check(p2, p1.x, "x") then
return false
end
elseif p1.z ~= p2.z then
if not move_check(p1, p2.z, "z") then
return false
end
if not move_check(p2, p1.z, "z") then
return false
end
else
return false
end
if not move_check(p1, p2.y, "y") then
return false
end
if not move_check(p2, p1.y, "y") then
return false
end
return true
end
-- tests if it's an obsidian portal
local function is_portal(pos)
for d=-3,3 do
for y=-4,4 do
local px = {x=pos.x+d, y=pos.y+y, z=pos.z}
local pz = {x=pos.x, y=pos.y+y, z=pos.z+d}
if check_portal(px, {x=px.x+3, y=px.y+4, z=px.z}) then
return px, {x=px.x+3, y=px.y+4, z=px.z}
end
if check_portal(pz, {x=pz.x, y=pz.y+4, z=pz.z+3}) then
return pz, {x=pz.x, y=pz.y+4, z=pz.z+3}
end
end
end
end
-- put here the function for creating a second portal
local create_second_portal
if mclike_portal then
function create_second_portal(target)
-- change target here
end
end
-- adds the violet portal essence
local function make_portal(pos)
local p1, p2 = is_portal(pos)
if not p1
or not p2 then
print("[nether] something failed.")
return false
end
local in_nether = p1.y < nether_start
if in_nether
and not mclike_portal then
print("[nether] aborted, obsidian portals can't be used to get out")
return
end
for d=1,2 do
for y=p1.y+1,p2.y-1 do
local p
if p1.z == p2.z then
p = {x=p1.x+d, y=y, z=p1.z}
else
p = {x=p1.x, y=y, z=p1.z+d}
end
if minetest.get_node(p).name ~= "air" then
return false
end
end
end
local param2
if p1.z == p2.z then
param2 = 0
else
param2 = 1
end
local target = {x=p1.x, y=p1.y, z=p1.z}
target.x = target.x + 1
if in_nether then
target.y = 0
create_second_portal(target)
else
target.y = portal_target + math.random(4)
end
if not generated_or_generate(target)
and mclike_portal then
return false
end
for d=0,3 do
for y=p1.y,p2.y do
local p
if param2 == 0 then
p = {x=p1.x+d, y=y, z=p1.z}
else
p = {x=p1.x, y=y, z=p1.z+d}
end
if minetest.get_node(p).name == "air" then
minetest.set_node(p, {name="nether:portal", param2=param2})
end
local meta = minetest.get_meta(p)
meta:set_string("p1", minetest.pos_to_string(p1))
meta:set_string("p2", minetest.pos_to_string(p2))
meta:set_string("target", minetest.pos_to_string(target))
end
end
print("[nether] construction accepted.")
return true
end
-- destroy the portal when destroying obsidian
minetest.override_item("default:obsidian", {
on_destruct = function(pos)
local meta = minetest.get_meta(pos)
local p1 = minetest.string_to_pos(meta:get_string("p1"))
local p2 = minetest.string_to_pos(meta:get_string("p2"))
local target = minetest.string_to_pos(meta:get_string("target"))
if not p1 or not p2 then
return
end
for x=p1.x,p2.x do
for y=p1.y,p2.y do
for z=p1.z,p2.z do
local nn = minetest.get_node({x=x,y=y,z=z}).name
if nn == "default:obsidian" or nn == "nether:portal" then
if nn == "nether:portal" then
minetest.remove_node({x=x,y=y,z=z})
end
local m = minetest.get_meta({x=x,y=y,z=z})
m:set_string("p1", "")
m:set_string("p2", "")
m:set_string("target", "")
end
end
end
end
meta = minetest.get_meta(target)
if not meta then
return
end
p1 = minetest.string_to_pos(meta:get_string("p1"))
p2 = minetest.string_to_pos(meta:get_string("p2"))
if not p1 or not p2 then
return
end
for x=p1.x,p2.x do
for y=p1.y,p2.y do
for z=p1.z,p2.z do
local nn = minetest.get_node({x=x,y=y,z=z}).name
if nn == "default:obsidian" or nn == "nether:portal" then
if nn == "nether:portal" then
minetest.remove_node({x=x,y=y,z=z})
end
local m = minetest.get_meta({x=x,y=y,z=z})
m:set_string("p1", "")
m:set_string("p2", "")
m:set_string("target", "")
end
end
end
end
end
})
-- override mese crystal fragment for making an obsidian portal
minetest.after(0.1, function()
minetest.override_item("default:mese_crystal_fragment", {
on_place = function(stack, player, pt)
if pt.under
and minetest.get_node(pt.under).name == "default:obsidian" then
local done = make_portal(pt.under)
if done then
local pname = player:get_player_name()
minetest.chat_send_player(pname,
"Warning: If you are in the nether you may not be " ..
"able to find the way out!")
if not minetest.is_creative_enabled(pname) then
stack:take_item()
end
end
end
return stack
end
})
end)
-- Get positions for an empty square around the origin
local function vector_square(r)
local tab, n = {}, 1
for i = -r+1, r do
for j = -1, 1, 2 do
local a, b = r*j, i*j
tab[n] = {a, -b}
tab[n+1] = {b, a}
n=n+2
end
end
return tab
end
local function is_netherportal(pos)
local x, y, z = pos.x, pos.y, pos.z
for _,i in pairs({-1, 3}) do
if minetest.get_node({x=x, y=y+i, z=z}).name ~= "nether:white" then
return
end
end
for _,sn in pairs(vector_square(1)) do
if minetest.get_node({x=x+sn[1], y=y-1, z=z+sn[2]}).name ~= "nether:netherrack"
or minetest.get_node({x=x+sn[1], y=y+3, z=z+sn[2]}).name ~= "nether:blood_cooked" then
return
end
end
for _,sn in pairs(vector_square(2)) do
if minetest.get_node({x=x+sn[1], y=y-1, z=z+sn[2]}).name ~= "nether:netherrack_black"
or minetest.get_node({x=x+sn[1], y=y+3, z=z+sn[2]}).name ~= "nether:wood_empty" then
return
end
end
for i = -1,1,2 do
for j = -1,1,2 do
if minetest.get_node({x=x+i, y=y+2, z=z+j}).name ~= "nether:apple" then
return
end
end
end
for i = -2,2,4 do
for j = 0,2 do
for k = -2,2,4 do
if minetest.get_node({x=x+i, y=y+j, z=z+k}).name ~= "nether:netherrack_brick_blue" then
return
end
end
end
end
for i = -1,1 do
for j = -1,1 do
if minetest.get_node({x=x+i, y=y+4, z=z+j}).name ~= "nether:wood_empty" then
return
end
end
end
return true
end
-- cache known portals
local known_portals_d = {}
local known_portals_u = {}
local function get_portal(t, z,x)
return t[z] and t[z][x]
end
local function set_portal(t, z,x, y)
t[z] = t[z] or {}
t[z][x] = y
end
local function get_player_nodepos(player)
local pos = player:get_pos()
pos.y = pos.y + player:get_properties().collisionbox[2] + 0.5
return vector.round(pos)
end
-- used when a player eats that fruit in a portal
function nether.teleport_player(player)
if not player then
minetest.log("error", "[nether] Missing player.")
return
end
local pos = get_player_nodepos(player)
if not is_netherportal(pos) then
return
end
minetest.sound_play("nether_teleporter", {pos=pos})
local meta = minetest.get_meta({x=pos.x, y=pos.y-1, z=pos.z})
if pos.y < nether_start then
set_portal(known_portals_d, pos.z,pos.x, pos.y)
local my = tonumber(meta:get_string("y"))
local y = get_portal(known_portals_u, pos.z,pos.x)
if y then
if y ~= my then
meta:set_string("y", y)
end
else
y = my or 100
end
pos.y = y - 0.3
player_from_nether(player, pos)
else
set_portal(known_portals_u, pos.z,pos.x, pos.y)
local my = tonumber(meta:get_string("y"))
local y = get_portal(known_portals_d, pos.z,pos.x)
if y then
if y ~= my then
meta:set_string("y", y)
end
else
y = my or portal_target+math.random(4)
end
pos.y = y - 0.3
player_to_nether(player, pos)
end
minetest.sound_play("nether_teleporter", {pos=pos})
return true
end

24
nether/settings.lua Normal file
View File

@ -0,0 +1,24 @@
local default_settings = {
trap_players = true,
log_to_chat = false,
log_level = 2,
overworld_help = true,
}
nether.settings = {} -- FIXME: unused field. store settings in here?
for name,dv in pairs(default_settings) do
local setting
local setting_name = "nether." .. name
if type(dv) == "boolean" then
setting = minetest.settings:get_bool(setting_name)
elseif type(dv) == "number" then
setting = tonumber(minetest.settings:get(setting_name))
else
error"[nether] Only boolean and number settings are available"
end
if setting == nil then
setting = dv
end
nether[name] = setting
end

23
nether/settingtypes.txt Normal file
View File

@ -0,0 +1,23 @@
# If enabled, regular players which are in the nether can leave it only with
# a nether portal and other ways of teleportation, e.g. the /spawn
# chatcommand, are blocked. Similarly, the nether can only be entered with a
# portal.
# This forces the players to investigate the nether and build a portal with
# hellish effort to go back to their home in the overworld.
# It is recommended to disable this setting in creative mode or if damage is
# disabled.
nether.trap_players (Trap players) bool true
# If enabled, show log messages in the chat and not only in debug.txt
nether.log_to_chat (Log messages to chat) bool false
# Specify how much text is printed for debugging purposes
# 0: Disabled
# 1: A bit of information
# 2: Acceptable amount of information
# 3: Lots of text
nether.log_level (Log level) int 2 0 3
# If disabled, players cannot view the nether guide with /nether_help
# in the overworld.
nether.overworld_help (Overworld help) bool true

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,166 +0,0 @@
-- Floor 1
{pos={x=0,y=0,z=0}, block="nether:netherrack"},
{pos={x=0,y=0,z=1}, block="nether:netherrack"},
{pos={x=0,y=0,z=2}, block="nether:netherrack"},
{pos={x=0,y=0,z=3}, block="nether:netherrack"},
{pos={x=0,y=0,z=4}, block="nether:netherrack"},
{pos={x=0,y=0,z=5}, block="nether:netherrack"},
{pos={x=1,y=0,z=5}, block="nether:netherrack"},
{pos={x=2,y=0,z=5}, block="nether:netherrack"},
{pos={x=3,y=0,z=5}, block="nether:netherrack"},
{pos={x=4,y=0,z=5}, block="nether:netherrack"},
{pos={x=5,y=0,z=5}, block="nether:netherrack"},
{pos={x=0,y=0,z=6}, block="nether:netherrack"},
{pos={x=1,y=0,z=6}, block="nether:netherrack"},
{pos={x=2,y=0,z=6}, block="nether:netherrack"},
{pos={x=3,y=0,z=6}, block="nether:netherrack"},
{pos={x=4,y=0,z=6}, block="nether:netherrack"},
{pos={x=5,y=0,z=6}, block="nether:netherrack"},
{pos={x=5,y=0,z=4}, block="nether:netherrack"},
{pos={x=5,y=0,z=3}, block="nether:netherrack"},
{pos={x=5,y=0,z=2}, block="nether:netherrack"},
{pos={x=5,y=0,z=1}, block="nether:netherrack"},
{pos={x=5,y=0,z=0}, block="nether:netherrack"},
{pos={x=4,y=0,z=0}, block="nether:netherrack"},
{pos={x=3,y=0,z=0}, block="nether:netherrack"},
{pos={x=2,y=0,z=0}, block="nether:netherrack"},
{pos={x=1,y=0,z=0}, block="nether:netherrack"},
-- Floor 2
{pos={x=0,y=1,z=0}, block="nether:netherrack"},
{pos={x=0,y=1,z=1}, block="nether:netherrack"},
{pos={x=0,y=1,z=2}, block="nether:netherrack"},
{pos={x=0,y=1,z=3}, block="nether:netherrack"},
{pos={x=0,y=1,z=4}, block="nether:netherrack"},
{pos={x=0,y=1,z=5}, block="nether:netherrack"},
{pos={x=1,y=1,z=5}, block="nether:netherrack"},
{pos={x=2,y=1,z=5}, block="nether:netherrack"},
{pos={x=3,y=1,z=5}, block="nether:netherrack"},
{pos={x=4,y=1,z=5}, block="nether:netherrack"},
{pos={x=5,y=1,z=5}, block="nether:netherrack"},
{pos={x=0,y=1,z=6}, block="nether:netherrack"},
{pos={x=1,y=1,z=6}, block="nether:netherrack"},
{pos={x=2,y=1,z=6}, block="nether:netherrack"},
{pos={x=3,y=1,z=6}, block="nether:netherrack"},
{pos={x=4,y=1,z=6}, block="nether:netherrack"},
{pos={x=5,y=1,z=6}, block="nether:netherrack"},
{pos={x=5,y=1,z=4}, block="nether:netherrack"},
{pos={x=5,y=1,z=3}, block="nether:netherrack"},
{pos={x=5,y=1,z=2}, block="nether:netherrack"},
{pos={x=5,y=1,z=1}, block="nether:netherrack"},
{pos={x=5,y=1,z=0}, block="nether:netherrack"},
{pos={x=4,y=1,z=0}, block="nether:netherrack"},
{pos={x=3,y=1,z=1}, block="nether:netherrack"},
{pos={x=2,y=1,z=1}, block="nether:netherrack"},
{pos={x=1,y=1,z=0}, block="nether:netherrack"},
{pos={x=1,y=1,z=1}, block="nether:netherrack"},
{pos={x=4,y=1,z=1}, block="nether:netherrack"},
-- Floor 3
{pos={x=0,y=2,z=0}, block="nether:netherrack"},
{pos={x=0,y=2,z=1}, block="nether:netherrack"},
{pos={x=0,y=2,z=2}, block="nether:netherrack"},
{pos={x=0,y=2,z=3}, block="nether:netherrack"},
{pos={x=0,y=2,z=4}, block="nether:netherrack"},
{pos={x=0,y=2,z=5}, block="nether:netherrack"},
{pos={x=1,y=2,z=5}, block="nether:netherrack"},
{pos={x=2,y=2,z=5}, block="nether:netherrack"},
{pos={x=3,y=2,z=5}, block="nether:netherrack"},
{pos={x=4,y=2,z=5}, block="nether:netherrack"},
{pos={x=5,y=2,z=5}, block="nether:netherrack"},
{pos={x=0,y=2,z=6}, block="nether:netherrack"},
{pos={x=1,y=2,z=6}, block="nether:netherrack"},
{pos={x=2,y=2,z=6}, block="nether:netherrack"},
{pos={x=3,y=2,z=6}, block="nether:netherrack"},
{pos={x=4,y=2,z=6}, block="nether:netherrack"},
{pos={x=5,y=2,z=6}, block="nether:netherrack"},
{pos={x=5,y=2,z=4}, block="nether:netherrack"},
{pos={x=5,y=2,z=3}, block="nether:netherrack"},
{pos={x=5,y=2,z=2}, block="nether:netherrack"},
{pos={x=5,y=2,z=1}, block="nether:netherrack"},
{pos={x=5,y=2,z=0}, block="nether:netherrack"},
{pos={x=4,y=2,z=0}, block="nether:netherrack"},
{pos={x=3,y=2,z=2}, block="nether:netherrack"},
{pos={x=2,y=2,z=2}, block="nether:netherrack"},
{pos={x=1,y=2,z=0}, block="nether:netherrack"},
{pos={x=1,y=2,z=1}, block="nether:netherrack"},
{pos={x=4,y=2,z=1}, block="nether:netherrack"},
{pos={x=1,y=2,z=2}, block="nether:netherrack"},
{pos={x=4,y=2,z=2}, block="nether:netherrack"},
-- Floor 4
{pos={x=0,y=3,z=0}, block="nether:netherrack"},
{pos={x=0,y=3,z=1}, block="nether:netherrack"},
{pos={x=0,y=3,z=2}, block="nether:netherrack"},
{pos={x=0,y=3,z=3}, block="nether:netherrack"},
{pos={x=0,y=3,z=4}, block="nether:netherrack"},
{pos={x=0,y=3,z=5}, block="nether:netherrack"},
{pos={x=1,y=3,z=5}, block="nether:netherrack"},
{pos={x=2,y=3,z=5}, block="nether:netherrack"},
{pos={x=3,y=3,z=5}, block="nether:netherrack"},
{pos={x=4,y=3,z=5}, block="nether:netherrack"},
{pos={x=5,y=3,z=5}, block="nether:netherrack"},
{pos={x=0,y=3,z=6}, block="nether:netherrack"},
{pos={x=1,y=3,z=6}, block="nether:netherrack"},
{pos={x=2,y=3,z=6}, block="nether:netherrack"},
{pos={x=3,y=3,z=6}, block="nether:netherrack"},
{pos={x=4,y=3,z=6}, block="nether:netherrack"},
{pos={x=5,y=3,z=6}, block="nether:netherrack"},
{pos={x=5,y=3,z=4}, block="nether:netherrack"},
{pos={x=5,y=3,z=3}, block="nether:netherrack"},
{pos={x=5,y=3,z=2}, block="nether:netherrack"},
{pos={x=5,y=3,z=1}, block="nether:netherrack"},
{pos={x=5,y=3,z=0}, block="nether:netherrack"},
{pos={x=4,y=3,z=0}, block="nether:netherrack"},
{pos={x=3,y=3,z=3}, block="nether:netherrack"},
{pos={x=2,y=3,z=3}, block="nether:netherrack"},
{pos={x=1,y=3,z=0}, block="nether:netherrack"},
{pos={x=1,y=3,z=1}, block="nether:netherrack"},
{pos={x=4,y=3,z=1}, block="nether:netherrack"},
{pos={x=1,y=3,z=2}, block="nether:netherrack"},
{pos={x=4,y=3,z=2}, block="nether:netherrack"},
{pos={x=1,y=3,z=3}, block="nether:netherrack"},
{pos={x=4,y=3,z=3}, block="nether:netherrack"},
{pos={x=1,y=3,z=4}, block="nether:netherrack"},
{pos={x=4,y=3,z=4}, block="nether:netherrack"},
{pos={x=2,y=3,z=4}, block="nether:netherrack"},
{pos={x=2,y=3,z=5}, block="nether:netherrack"},
{pos={x=3,y=3,z=4}, block="nether:netherrack"},
{pos={x=3,y=3,z=5}, block="nether:netherrack"},
-- Floor 5
{pos={x=2,y=4,z=4}, block="nether:netherrack"},
{pos={x=2,y=4,z=5}, block="nether:netherrack"},
{pos={x=3,y=4,z=4}, block="nether:netherrack"},
{pos={x=3,y=4,z=5}, block="nether:netherrack"},
{pos={x=2,y=4,z=6}, block="nether:netherrack"},
{pos={x=3,y=4,z=6}, block="nether:netherrack"},
-- Torches on floor 5
{pos={x=0,y=4,z=4}, block="nether:nether_torch_bottom"},
{pos={x=1,y=4,z=4}, block="nether:nether_torch_bottom"},
{pos={x=0,y=4,z=5}, block="nether:nether_torch_bottom"},
{pos={x=1,y=4,z=5}, block="nether:nether_torch_bottom"},
{pos={x=4,y=4,z=4}, block="nether:nether_torch_bottom"},
{pos={x=5,y=4,z=4}, block="nether:nether_torch_bottom"},
{pos={x=4,y=4,z=5}, block="nether:nether_torch_bottom"},
{pos={x=5,y=4,z=5}, block="nether:nether_torch_bottom"},
{pos={x=0,y=4,z=0}, block="nether:nether_torch_bottom"},
{pos={x=1,y=4,z=0}, block="nether:nether_torch_bottom"},
{pos={x=0,y=4,z=1}, block="nether:nether_torch_bottom"},
{pos={x=1,y=4,z=1}, block="nether:nether_torch_bottom"},
{pos={x=4,y=4,z=0}, block="nether:nether_torch_bottom"},
{pos={x=5,y=4,z=0}, block="nether:nether_torch_bottom"},
{pos={x=4,y=4,z=1}, block="nether:nether_torch_bottom"},
{pos={x=5,y=4,z=1}, block="nether:nether_torch_bottom"},
{pos={x=0,y=4,z=2}, block="nether:nether_torch_bottom"},
{pos={x=1,y=4,z=2}, block="nether:nether_torch_bottom"},
{pos={x=0,y=4,z=3}, block="nether:nether_torch_bottom"},
{pos={x=1,y=4,z=3}, block="nether:nether_torch_bottom"},
{pos={x=4,y=4,z=2}, block="nether:nether_torch_bottom"},
{pos={x=5,y=4,z=2}, block="nether:nether_torch_bottom"},
{pos={x=4,y=4,z=3}, block="nether:nether_torch_bottom"},
{pos={x=5,y=4,z=3}, block="nether:nether_torch_bottom"},
{pos={x=4,y=4,z=6}, block="nether:nether_torch_bottom"},
{pos={x=5,y=4,z=6}, block="nether:nether_torch_bottom"},
-- Floor 6
{pos={x=2,y=5,z=6}, block="nether:netherrack"},
{pos={x=3,y=5,z=6}, block="nether:netherrack"},
-- Floor 7
{pos={x=2,y=6,z=6}, block="nether:netherrack"},
{pos={x=3,y=6,z=6}, block="nether:netherrack"},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 B

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 807 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 B

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 660 B

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

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