mirror of
https://github.com/minetest-mods/nether.git
synced 2025-06-28 22:46:18 +02:00
Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
92431f2303 | |||
bd28f97946 | |||
b51b831483 | |||
01b6f3c56d | |||
a6d1f55f0a | |||
d16b530685 | |||
ea677c5a1b | |||
21c7e2801d | |||
3470b1e22e | |||
3e809a811b | |||
6c6a182366 | |||
9c1fa2c843 | |||
957fdc887b | |||
7dc32f6bb8 | |||
a8a6bb00c5 | |||
12ca98c25a | |||
a03375c5a4 | |||
d3f79e961b | |||
d8e6a6aca3 | |||
247ca0844b |
@ -27,8 +27,11 @@ read_globals = {
|
||||
"stairsplus",
|
||||
"string.split",
|
||||
table = { fields = { "copy", "getn" } },
|
||||
"toolranks",
|
||||
"vector",
|
||||
"VoxelArea",
|
||||
"VoxelManip",
|
||||
"walls",
|
||||
xpanes = { fields = { "register_pane" } },
|
||||
}
|
||||
|
||||
|
14
README.md
14
README.md
@ -16,6 +16,8 @@ right-click/used on the frame to activate it.
|
||||
|
||||
See portal_api.txt for how to create custom portals to your own realms.
|
||||
|
||||
Nether Portals can allow surface fast-travel.
|
||||
|
||||
This mod provides Nether basalts (natural, hewn, and chiseled) as nodes which
|
||||
require a player to journey to the magma ocean to obtain, so these can be used
|
||||
for gating progression through a game. For example, a portal to another realm
|
||||
@ -24,8 +26,7 @@ the nether first, or basalt might be a crafting ingredient required to reach
|
||||
a particular branch of the tech-tree.
|
||||
|
||||
Netherbrick tools are provided (pick, shovel, axe, & sword), see tools.lua
|
||||
|
||||
Nether Portals can allow surface fast-travel.
|
||||
The Nether pickaxe has a 10x bonus against wear when mining netherrack.
|
||||
|
||||
|
||||
## License of source code:
|
||||
@ -50,9 +51,11 @@ SOFTWARE.
|
||||
### [Public Domain Dedication (CC0 1.0)](https://creativecommons.org/publicdomain/zero/1.0/)
|
||||
|
||||
* `nether_portal_teleport.ogg` is a timing adjusted version of "teleport" by [outroelison](https://freesound.org/people/outroelison), used under CC0 1.0
|
||||
* `nether_rack_destroy.ogg` is from "Rock destroy" by [Bertsz](https://freesound.org/people/Bertsz/), used under CC0 1.0
|
||||
|
||||
### [Attribution 3.0 Unported (CC BY 3.0)](https://creativecommons.org/licenses/by/3.0/)
|
||||
|
||||
* `nether_lightstaff.ogg` is "Fire Burst" by [SilverIllusionist](https://freesound.org/people/SilverIllusionist/), 2019
|
||||
* `nether_portal_ambient.ogg` & `nether_portal_ambient.0.ogg` are extractions from "Deep Cinematic Rumble Stereo" by [Patrick Lieberkind](http://www.lieberkindvisuals.dk), used under CC BY 3.0
|
||||
* `nether_portal_extinguish.ogg` is an extraction from "Tight Laser Weapon Hit Scifi" by [damjancd](https://freesound.org/people/damjancd), used under CC BY 3.0
|
||||
* `nether_portal_ignite.ogg` is a derivative of "Flame Ignition" by [hykenfreak](https://freesound.org/people/hykenfreak), used under CC BY 3.0. "Nether Portal ignite" is licensed under CC BY 3.0 by Treer.
|
||||
@ -60,9 +63,13 @@ SOFTWARE.
|
||||
### [Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/)
|
||||
* `nether_basalt`* (files starting with "nether_basalt"): Treer, 2020
|
||||
* `nether_book_`* (files starting with "nether_book"): Treer, 2019-2020
|
||||
* `nether_brick_deep.png`: Treer, 2021
|
||||
* `nether_fumarole.ogg`: Treer, 2020
|
||||
* `nether_geode.png`: Treer, 2021
|
||||
* `nether_geode_glass.png`: Treer, 2021
|
||||
* `nether_lava_bubble`* (files starting with "nether_lava_bubble"): Treer, 2020
|
||||
* `nether_lava_crust_animated.png`: Treer, 2019-2020
|
||||
* `nether_lightstaff.png`: Treer, 2021
|
||||
* `nether_particle_anim`* (files starting with "nether_particle_anim"): Treer, 2019
|
||||
* `nether_portal_ignition_failure.ogg`: Treer, 2019
|
||||
* `nether_smoke_puff.png`: Treer, 2020
|
||||
@ -74,7 +81,4 @@ SOFTWARE.
|
||||
* `nether_rack`* (files starting with "nether_rack"): Zeg9
|
||||
* `nether_tool_`* (files starting with "nether_tool_"): color adjusted versions from "[default](https://github.com/minetest/minetest_game/tree/master/mods/default)" mod, originals by BlockMen
|
||||
|
||||
### [Unlicensed but permission for inclusion by kovaszos_uborka](https://www.planetminecraft.com/member/kovaszos_uborka/)
|
||||
* `nether_brick_deep.png` (edited by TenPlus1)
|
||||
|
||||
All other media: Copyright © 2013 PilzAdam, licensed under CC BY-SA 3.0 by PilzAdam.
|
||||
|
@ -7,3 +7,4 @@ loot?
|
||||
mesecons?
|
||||
moreblocks?
|
||||
climate_api?
|
||||
xpanes?
|
4
init.lua
4
init.lua
@ -312,7 +312,7 @@ The expedition parties have found no diamonds or gold, and after an experienced
|
||||
geodeSky.sky_data.base_color = nether.fogColor.geodes
|
||||
|
||||
climate_api.register_weather(
|
||||
"nether:nether",
|
||||
"nether:caverns",
|
||||
{ nether_biome = "nether" },
|
||||
{ ["climate_api:skybox"] = netherSky }
|
||||
)
|
||||
@ -345,4 +345,4 @@ minetest.register_on_dieplayer(
|
||||
)
|
||||
end
|
||||
end
|
||||
)
|
||||
)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# textdomain: nether
|
||||
|
||||
# Translation FR by Louis Royer
|
||||
# Translation FR by Louis Royer and JoeEnderman
|
||||
|
||||
|
||||
### init.lua ###
|
||||
@ -15,57 +15,76 @@ Nether Portal=Portail du Nether
|
||||
|
||||
### mapgen_mantle.lua ###
|
||||
|
||||
, @1m above lava-sea level=
|
||||
, @1m below lava-sea level=
|
||||
, approaching y boundary of Nether=
|
||||
, @1m above lava-sea level=, @1m au-dessus du niveau de la mer de lave
|
||||
, @1m below lava-sea level=, @1m en-dessous du niveau de la mer de lave
|
||||
, approaching y boundary of Nether=, approchant de la limite y du Nether
|
||||
@1@2@3@4=
|
||||
Center/Mantle, but outside the caverns=
|
||||
Center/Mantle, inside cavern=
|
||||
Describes which region of the nether the player is in=
|
||||
Negative nether=
|
||||
Positive nether=
|
||||
Shell between negative nether and center region=
|
||||
Shell between positive nether and center region=
|
||||
The Overworld=
|
||||
Unknown player position=
|
||||
Center/Mantle, but outside the caverns=Centre/Manteau, mais à l'extérieur des cavernes
|
||||
Center/Mantle, inside cavern=Centre/Manteau, à l'intérieur d'une caverne
|
||||
Describes which region of the nether the player is in=Indique dans quelle région du Nether se trouve le joueur
|
||||
Negative nether=Nether négatif
|
||||
Positive nether=Nether positif
|
||||
Shell between negative nether and center region=Coquille entre le Nether négatif et la région centrale
|
||||
Shell between positive nether and center region=Coquille entre le Nether positif et la région centrale
|
||||
The Overworld=L'Overworld
|
||||
Unknown player position=Position du joueur inconnue
|
||||
[Perlin @1] =
|
||||
|
||||
### nodes.lua ###
|
||||
|
||||
A finely finished block of solid Nether Basalt.=
|
||||
A rough cut solid block of Nether Basalt.=
|
||||
A thin crust of cooled lava with liquid lava beneath=
|
||||
A vent in the earth emitting steam and gas=
|
||||
Can be repurposed to provide puffs of smoke in a chimney=
|
||||
Chiselled Basalt=
|
||||
A Deep Netherrack Wall=Un mur profond en Netherrack
|
||||
A Netherrack Wall=Un mur en Netherrack
|
||||
A finely finished block of solid Nether Basalt.=Un bloc fini de basalte du Nether solide.
|
||||
A rough cut solid block of Nether Basalt.=Un bloc solide de basalte du Nether taillé à la hache.
|
||||
A thin crust of cooled lava with liquid lava beneath=Une croûte fine de lave refroidie avec de la lave liquide en dessous
|
||||
A vent in the earth emitting steam and gas=Une fissure dans la terre émettant de la vapeur et du gaz
|
||||
Can be repurposed to provide puffs of smoke in a chimney=Peut être réutilisé pour produire des bouffées de fumée dans une cheminée
|
||||
Chiselled Basalt=Basalte sculpté
|
||||
|
||||
Columns of dark basalt found only in magma oceans deep within the Nether.=
|
||||
Columns of dark basalt found only in magma oceans deep within the Nether.=Colonnes de basalte noir que l'on trouve uniquement dans les océans de magma profonds du Nether.
|
||||
|
||||
Compressed Netherbrick=
|
||||
Cracked Nether Brick=
|
||||
Deep Glowstone=
|
||||
Deep Netherrack=
|
||||
Fumarolic Chimney=
|
||||
Fumarolic Chimney Corner=
|
||||
Fumarolic Chimney Slab=
|
||||
Compressed Netherbrick=Briques du Nether compressées
|
||||
Cracked Nether Brick=Briques du Nether craquelées
|
||||
Deep Glowstone=Pierre lumineuse profonde
|
||||
Deep Nether Brick=Briques du Nether profondes
|
||||
Deep Nether Slab=Dalle du Nether profonde
|
||||
Deep Nether Stair=Escalier du Nether profond
|
||||
Deep Netherrack=Netherrack profond
|
||||
Deep Netherrack Slab=Dalle de Netherrack profonde
|
||||
Deep Netherrack Stair=Escalier de Netherrack profond
|
||||
Fumarolic Chimney=Cheminée fumarolique
|
||||
Fumarolic Chimney Corner=Coin de cheminée fumarolique
|
||||
Fumarolic Chimney Slab=Dalle de cheminée fumarolique
|
||||
Glowstone=Pierre lumineuse
|
||||
Hewn Basalt=
|
||||
Hewn Basalt=Basalte taillé
|
||||
Inner Deep Nether Stair=Escalier intérieur du Nether profond
|
||||
Inner Nether Stair=Escalier intérieur du Nether
|
||||
Lava Crust=
|
||||
Lava Crust=Croûte de lave
|
||||
|
||||
Lava crust is strong enough to walk on, but still hot enough to inflict burns.=
|
||||
Lava crust is strong enough to walk on, but still hot enough to inflict burns.=La croûte de lave est assez solide pour marcher dessus, mais encore assez chaude pour causer des brûlures
|
||||
|
||||
Nether Basalt=
|
||||
Nether Basalt=Basalte du Nether
|
||||
Nether Beryl=Béryl du Nether
|
||||
Nether Berylite=Bérylite du Nether
|
||||
Nether Brick=Brique du Nether
|
||||
Nether Brick Fence=Barrière en briques du Nether
|
||||
Nether Brick Fence Rail=Rail de barrière en briques du Nether
|
||||
Nether Crystal Pane=Panneau de cristal du Nether
|
||||
Nether Slab=Dalle du Nether
|
||||
Nether Stair=Escalier du Nether
|
||||
|
||||
Nether geode crystal, found lining the interior walls of Nether geodes=Cristal de géode du Nether, trouvé le long des parois intérieures des géodes du Nether
|
||||
|
||||
Nether geode crystal. A crystalline structure with faint glow found inside large Nether geodes=Cristal de géode du Nether. Une structure cristalline avec une faible lueur trouvée à l'intérieur des grandes géodes du Nether.
|
||||
|
||||
Netherrack=Roche du Nether
|
||||
Netherrack from deep in the mantle=
|
||||
Netherrack stair=
|
||||
Netherrack from deep in the mantle=Roche du Nether provenant des profondeurs du manteau
|
||||
Netherrack Slab=Dalle du Nether
|
||||
Netherrack Stair=Escalier du Nether
|
||||
Nethersand=Sable du Nether
|
||||
Outer Deep Nether Stair=Escalier extérieur profond du Nether
|
||||
Outer Nether Stair=Escalier extérieur du Nether
|
||||
Portal=
|
||||
Portal=Portail
|
||||
|
||||
### portal_api.lua ###
|
||||
|
||||
@ -82,7 +101,7 @@ In all my travels, and time spent in the Great Libraries, I have encountered no
|
||||
|
||||
In all my travels, and time spent in the Great Libraries, I have encountered no shortage of legends surrounding preternatural doorways said to open into other worlds, yet only one can I confirm as being more than merely a story.=Après tous mes voyages, et le temps passé dans les Grandes Bibliothèques, je ne manque pas de légendes sur les portes surnaturelles qui, dit-on s’ouvrent vers d’autres mondes, mais seul une personne peut confirmer que ce sont plus que de simples histoires.
|
||||
|
||||
Mysterious forces prevented you from opening that portal. Please try another location=
|
||||
Mysterious forces prevented you from opening that portal. Please try another location=Des forces mystérieuses vous empêchent d'ouvrir ce portail. Veuillez essayer un autre emplacement.
|
||||
|
||||
Portal wormhole=Vortex du portail
|
||||
|
||||
@ -107,9 +126,16 @@ There is a floating land of hills and forests up there, over the edges of which
|
||||
|
||||
### tools.lua ###
|
||||
|
||||
Nether Axe=
|
||||
Nether Ingot=
|
||||
Nether Lump=
|
||||
Nether Pickaxe=
|
||||
Nether Shovel=
|
||||
Nether Sword=
|
||||
Nether Axe=Hache du Nether
|
||||
Nether Ingot=Lingot du Nether
|
||||
Nether Lump=Morceau du Nether
|
||||
Nether Pickaxe@nWell suited for mining netherrack=Pioche du Nether@nBien adaptée pour miner la roche du Nether
|
||||
Nether Shovel=Pelle du Nether
|
||||
Nether Sword=Épée du Nether
|
||||
|
||||
Nether staff of Eternal Light@nCreates glowstone from netherrack=Bâton du Nether de lumière éternelle@nCrée des blocs de pierre lumineuse à partir de roche du Nether
|
||||
|
||||
Nether staff of Light@nTemporarily transforms the netherrack into glowstone=Bâton du Nether de lumière@nTransforme temporairement la roche du Nether en blocs de pierre lumineuse
|
||||
|
||||
Uniquely suited for mining netherrack, with minimal wear when doing so. Blunts quickly on other materials.=Convient parfaitement pour miner la roche du Nether avec une usure minimale. S'émousse rapidement sur les autres matériaux.
|
||||
|
||||
|
140
locale/nether.ru.tr
Normal file
140
locale/nether.ru.tr
Normal file
@ -0,0 +1,140 @@
|
||||
# textdomain: nether
|
||||
|
||||
|
||||
|
||||
### init.lua ###
|
||||
|
||||
Construction requires 14 blocks of obsidian, which we found deep underground where water had solidified molten rock. The finished frame is four blocks wide, five blocks high, and stands vertically, like a doorway.@n@nThis opens to a truly hellish place, though for small mercies the air there is still breathable. There is an intriguing dimensional mismatch happening between this realm and ours, as after opening the second portal into it we observed that 10 strides taken in the Nether appear to be an equivalent of @1 in the natural world.@n@nThe expedition parties have found no diamonds or gold, and after an experienced search party failed to return from the trail of a missing expedition party, I must conclude this is a dangerous place.=Конструкция требует 14 блоков обсидиана, который можно найти глубоко под землей, где с помощью воды затвердевает расплавленный камень. Законченная рамка в 4 блока шириной, 5 в высоту, стоящая вертикально как дверной проем.@n@nОткрывает действительно адское место, к счастью воздух здесь все еще пригоден для дыхания. После открытия второго портала в Незер мы обнаружили, что между этим миром и нашим происходит некое искривление простанства, благодаря которому 10 шагов в Незере равны @1 в нашем мире.@n@nРазведывательные команды не нашли золота или алмазов, и после того как опытная исследовательская команда сбилась со следа пропавшей команды, я вынужден констатировать, что это действительно опасное место.
|
||||
|
||||
|
||||
### init.lua ###
|
||||
### nodes.lua ###
|
||||
|
||||
Nether Portal=Незер-портал
|
||||
|
||||
### mapgen_mantle.lua ###
|
||||
|
||||
, @1m above lava-sea level=, @1м над уровнем моря лавы
|
||||
, @1m below lava-sea level=, @1м под уровнем моря лавы
|
||||
, approaching y boundary of Nether=, приближаетесь к y границы Незера
|
||||
@1@2@3@4=
|
||||
Center/Mantle, but outside the caverns=Центр/мантия, но вне пещер
|
||||
Center/Mantle, inside cavern=Центр/мантия, внутри пещеры
|
||||
Describes which region of the nether the player is in=Описывает в каком регионе Незера находится игрок
|
||||
Negative nether=Отрицательный Незер
|
||||
Positive nether=Положительный Незер
|
||||
Shell between negative nether and center region=Оболочка между отрицательным Незер и центральным регионом
|
||||
Shell between positive nether and center region=Оболочка между положительным Незер и центральным регионом
|
||||
The Overworld=Внешний мир
|
||||
Unknown player position=Неизвестная положение игрока
|
||||
[Perlin @1] =
|
||||
|
||||
### nodes.lua ###
|
||||
|
||||
A Deep Netherrack Wall=Стена глубинного адского камня
|
||||
A Netherrack Wall=Стена адского камня
|
||||
A finely finished block of solid Nether Basalt.=Прекрасно обработанный блок незер-базальта.
|
||||
A rough cut solid block of Nether Basalt.=Грубо разрезанный блок незер-базальта.
|
||||
A thin crust of cooled lava with liquid lava beneath=Тонкая корка охлажденной лавы с жидкой лавой под ней.
|
||||
A vent in the earth emitting steam and gas=Отверстие в земле, испускающее пар и газ
|
||||
Can be repurposed to provide puffs of smoke in a chimney=Может быть использован для создания клубов дыма в дымоходе
|
||||
Chiselled Basalt=Высеченный базальт
|
||||
|
||||
Columns of dark basalt found only in magma oceans deep within the Nether.=Колонный темного базальта можно наяти только в океанах магмы глубоко внутри Незера.
|
||||
|
||||
Compressed Netherbrick=Сжаты незер-кирпич
|
||||
Cracked Nether Brick=Треснутый незер-кирпич
|
||||
Deep Glowstone=Глубинный светокамень
|
||||
Deep Nether Brick=Глубинный незер-кирпич
|
||||
Deep Nether Slab=Глубинные незер (плита)
|
||||
Deep Nether Stair=Глубинные незер (ступени)
|
||||
Deep Netherrack=Глубинный адский камень
|
||||
Deep Netherrack Slab=Глубинный адский камень (плита)
|
||||
Deep Netherrack Stair=Глубинный адский камень (ступени)
|
||||
Fumarolic Chimney=Фумарольный дымоход
|
||||
Fumarolic Chimney Corner=Уголь фумарольного дымохода
|
||||
Fumarolic Chimney Slab=Плита фумарольного дымохода
|
||||
Glowstone=Светокамень
|
||||
Hewn Basalt=Высеченный базальт
|
||||
Inner Deep Nether Stair=Внутренние ступени из глубинного незера
|
||||
Inner Nether Stair=Внутренние ступени из незера
|
||||
Lava Crust=Лавовая корка
|
||||
|
||||
Lava crust is strong enough to walk on, but still hot enough to inflict burns.=Лавовая кока достаточно прочна, чтобы по ней ходить, однако также достаточно горяча, чтобы вызвать ожоги.
|
||||
|
||||
Nether Basalt=Незер-базальт
|
||||
Nether Beryl=Незер-берилл
|
||||
Nether Berylite=Незер-бериллит
|
||||
Nether Brick=Незер-кирпич
|
||||
Nether Brick Fence=Забор из незер-кирпича
|
||||
Nether Brick Fence Rail=Перила забора из незер-кирпича
|
||||
Nether Crystal Pane=Панель из незер-кристалла
|
||||
Nether Slab=Незер-плита
|
||||
Nether Stair=Незер-ступени
|
||||
|
||||
Nether geode crystal, found lining the interior walls of Nether geodes=Кристалл жеоды Незера, выстилает изнутри стены жеод Незера.
|
||||
|
||||
Nether geode crystal. A crystalline structure with faint glow found inside large Nether geodes=Кристалл жеоды Незера. Кристаллическая структура со слабым свечением, которую можно обнаружить внутри больших жеод Незера.
|
||||
|
||||
Netherrack=Адский камень
|
||||
Netherrack from deep in the mantle=Адский камень из глубины мантии
|
||||
Netherrack Slab=Адский камень (плита)
|
||||
Netherrack Stair=Адский камень (ступени)
|
||||
Nethersand=Незер-песок
|
||||
Outer Deep Nether Stair=Внешние ступени из глубинного незера
|
||||
Outer Nether Stair=Внешние ступени из незера
|
||||
Portal=Портал
|
||||
|
||||
### portal_api.lua ###
|
||||
|
||||
@n@nThe key to opening such a doorway is to strike the frame with a @1, at which point the very air inside begins to crackle and glow.=@n@nКлюч к открытию такого прохода - это высечь пламя с помощью @1, при этом сам воздух внутри начинает трещать и светиться.
|
||||
|
||||
A definitive guide to Rifts and Portals=Полное руководство по разломам и порталам
|
||||
|
||||
A guidebook for how to build portals to other realms. It can sometimes be found in dungeon chests, however a copy of this book is not needed as its contents are included in this Encyclopedia.=Руководство по стоительству порталов в другие миры. Может быть иногда обнаружено в сундуках подземелий, хотя копия этой книги не требуется, так как ее содержимое включено в эту Энциклопедию.
|
||||
|
||||
Book of Portals=Книга порталов
|
||||
Building Portals=Строительство порталов
|
||||
|
||||
In all my travels, and time spent in the Great Libraries, I have encountered no shortage of legends surrounding preternatural doorways said to open into other worlds, yet only @1 can I confirm as being more than merely stories.=Во время своих путешествий и долгих часов, проведённых в Великих Библиотеках, я обнаружил множество легенд о сверхъестественных порталах в иные миры. Лишь в @n случаях я могу подтвердить, что это не просто сказки.
|
||||
|
||||
In all my travels, and time spent in the Great Libraries, I have encountered no shortage of legends surrounding preternatural doorways said to open into other worlds, yet only one can I confirm as being more than merely a story.=Во время своих путешествий и долгих часов, проведённых в Великих Библиотеках, я обнаружил множество легенд о сверхъестественных порталах в иные миры. Лишь в одном случае я могу подтвердить, что это не просто сказки.
|
||||
|
||||
Mysterious forces prevented you from opening that portal. Please try another location=Мистические силы не дают Вам открыть этот портал. Пожалуйста, попробуйте в другом месте.
|
||||
|
||||
Portal wormhole=Червоточина портала
|
||||
|
||||
Portals to other realms can be opened by building a frame in the right shape with the right blocks, then using an item to activate it. A local copy of the guidebook to portals is published below.@n---@n@n=Порталы в другие миры могут быть открыты с помощью рамки нужной формы из правильных блоков, а также с помощью предмета для активации. Локальная копия руководства по порталам находится ниже.@n---@n@n
|
||||
|
||||
Refer: "Help" > "Basics" > "Building Portals"=Оглавление: "Помощь" > "Основы" > "Строительство порталов"
|
||||
Untitled portal=Портал без названия
|
||||
We know almost nothing about this portal=Мы ничего не знаем об этом портале
|
||||
|
||||
### portal_examples.lua ###
|
||||
|
||||
Floatlands Portal=Портал на Парящие Острова
|
||||
|
||||
Requiring 16 blocks of tin and constructed in a circular fashion, a finished frame is seven blocks wide, seven blocks high, and stands vertically like a doorway.@n@nThese travel a distance along the ground, and even when constructed deep underground will link back up to the surface. They appear to favor a strange direction, with the exit portal linking back only for as long as the portal stays open — attempting to reopen a portal from the exit doorway leads to a new destination along this favored direction. It has stymied our ability to study the behavior of these portals because without constructing dual portals and keeping both open it's hard to step through more than one and still be able to return home.@n@nDue to such difficulties, we never learned what determines the direction and distance where the matching twin portal will appear, and I have lost my friend and protégé. In cavalier youth and with little more than a rucksack, Coudreau has decided to follow the chain as far as it goes, and has not been seen since. Coudreau believes it works in epicycles, but I am not convinced. Still, I cling to the hope that one day the portal will open and Coudreau will step out from whichever place leads to this one, perhaps with an epic tale to tell.=Для создания портала требуется 16 блоков олова, выложенных по кругу; готовая рама достигает семи блоков в ширину и высоту, стоя вертикально, подобно двери.@n@nЭти порталы могут вести на большое расстояние, и даже если они построены глубоко под землёй, их выход зачастую находится на поверхности. Порталы, похоже, следуют странному направлению, где выход ведёт обратно только до тех пор, пока портал остаётся открытым. Если попытаться открыть портал заново из выходной точки, он приведёт в новое место по этому загадочному маршруту. Это осложняет наше изучение этих порталов, ведь без одновременного поддержания работы двух порталов трудно пройти через один из них и всё же вернуться обратно.@n@nИз-за таких трудностей мы так и не выяснили, что определяет направление и расстояние, на котором появится связанный портал. Я потерял друга и ученика. С юношеской бесшабашностью и с одним лишь рюкзаком на плечах, Кудро решил следовать по цепи порталов до самого конца и с тех пор не давал о себе знать. Кудро полагает, что порталы работают по принципу эпициклов, но я не убеждён. Тем не менее, я надеюсь, что однажды портал откроется и Кудро выйдет из него — оттуда, куда ведёт этот портал, — и, возможно, расскажет нам эпическую историю о своих странствиях.
|
||||
|
||||
Requiring 21 blocks of ice, and constructed in the shape of a 3 × 3 platform with walls, or like a bowl. A finished platform is 2 blocks high, and 5 blocks wide at the widest in both directions.@n@nThis portal is different to the others, rather than acting akin to a doorway it appears to the eye more like a small pool of water which can be stepped into. Upon setting foot in the portal we found ourselves at a tremendous altitude.@1=Для создания этого портала требуется 21 блок льда, выложенных в форме платформы 3 × 3 с боковыми стенками, напоминающей чашу. Завершённая конструкция достигает высоты двух блоков и в самой широкой части составляет пять блоков в обе стороны.@n@nВ отличие от других порталов, этот скорее напоминает маленький водоём, в который можно шагнуть, чем обычную дверную арку. Когда мы ступили на поверхность портала, то внезапно оказались на невероятной высоте.@1
|
||||
|
||||
Surface Portal=Поверхностный портал
|
||||
|
||||
There is a floating land of hills and forests up there, over the edges of which is a perilous drop all the way back down to sea level. We have not found how far these pristine lands extend. I have half a mind to retire there one day.=Там, наверху, простирается парящий мир холмов и лесов, с опасными обрывами, за которыми — головокружительное падение обратно до самого уровня моря. Насколько далеко раскинулись эти нетронутые земли, мы пока не знаем. Порой я ловлю себя на мысли, что однажды стоило бы уйти туда навсегда.
|
||||
|
||||
|
||||
### tools.lua ###
|
||||
|
||||
Nether Axe=Незер-топор
|
||||
Nether Ingot=Незер-слиток
|
||||
Nether Lump=Кусок незера
|
||||
Nether Pickaxe@nWell suited for mining netherrack=Незер-кирка@nХорошо подходит для копания адского камня
|
||||
Nether Shovel=Незер-лопата
|
||||
Nether Sword=Незер-меч
|
||||
|
||||
Nether staff of Eternal Light@nCreates glowstone from netherrack=Незер-посох Вечного Света@nСоздает светокамень из адского камня
|
||||
|
||||
Nether staff of Light@nTemporarily transforms the netherrack into glowstone=Незер-посох Света@nВременно превращает адский камень в светокамень
|
||||
|
||||
Uniquely suited for mining netherrack, with minimal wear when doing so. Blunts quickly on other materials.=Идеально подходит для добычи адского камня, почти не изнашиваясь при этом. Однако быстро тупится при работе с другими материалами.
|
||||
|
@ -31,6 +31,8 @@ Unknown player position=
|
||||
|
||||
### nodes.lua ###
|
||||
|
||||
A Deep Netherrack Wall=
|
||||
A Netherrack Wall=
|
||||
A finely finished block of solid Nether Basalt.=
|
||||
A rough cut solid block of Nether Basalt.=
|
||||
A thin crust of cooled lava with liquid lava beneath=
|
||||
@ -43,26 +45,43 @@ Columns of dark basalt found only in magma oceans deep within the Nether.=
|
||||
Compressed Netherbrick=
|
||||
Cracked Nether Brick=
|
||||
Deep Glowstone=
|
||||
Deep Nether Brick=
|
||||
Deep Nether Slab=
|
||||
Deep Nether Stair=
|
||||
Deep Netherrack=
|
||||
Deep Netherrack Slab=
|
||||
Deep Netherrack Stair=
|
||||
Fumarolic Chimney=
|
||||
Fumarolic Chimney Corner=
|
||||
Fumarolic Chimney Slab=
|
||||
Glowstone=
|
||||
Hewn Basalt=
|
||||
Inner Deep Nether Stair=
|
||||
Inner Nether Stair=
|
||||
Lava Crust=
|
||||
|
||||
Lava crust is strong enough to walk on, but still hot enough to inflict burns.=
|
||||
|
||||
Nether Basalt=
|
||||
Nether Beryl=
|
||||
Nether Berylite=
|
||||
Nether Brick=
|
||||
Nether Brick Fence=
|
||||
Nether Brick Fence Rail=
|
||||
Nether Crystal Pane=
|
||||
Nether Slab=
|
||||
Nether Stair=
|
||||
|
||||
Nether geode crystal, found lining the interior walls of Nether geodes=
|
||||
|
||||
Nether geode crystal. A crystalline structure with faint glow found inside large Nether geodes=
|
||||
|
||||
Netherrack=
|
||||
Netherrack from deep in the mantle=
|
||||
Netherrack stair=
|
||||
Netherrack Slab=
|
||||
Netherrack Stair=
|
||||
Nethersand=
|
||||
Outer Deep Nether Stair=
|
||||
Outer Nether Stair=
|
||||
Portal=
|
||||
|
||||
@ -109,6 +128,13 @@ There is a floating land of hills and forests up there, over the edges of which
|
||||
Nether Axe=
|
||||
Nether Ingot=
|
||||
Nether Lump=
|
||||
Nether Pickaxe=
|
||||
Nether Pickaxe@nWell suited for mining netherrack=
|
||||
Nether Shovel=
|
||||
Nether Sword=
|
||||
|
||||
Nether staff of Eternal Light@nCreates glowstone from netherrack=
|
||||
|
||||
Nether staff of Light@nTemporarily transforms the netherrack into glowstone=
|
||||
|
||||
Uniquely suited for mining netherrack, with minimal wear when doing so. Blunts quickly on other materials.=
|
||||
|
||||
|
22
mapgen.lua
22
mapgen.lua
@ -71,6 +71,7 @@ end
|
||||
-- Load specialty helper functions
|
||||
dofile(nether.path .. "/mapgen_dungeons.lua")
|
||||
dofile(nether.path .. "/mapgen_mantle.lua")
|
||||
dofile(nether.path .. "/mapgen_geodes.lua")
|
||||
|
||||
|
||||
-- Misc math functions
|
||||
@ -170,7 +171,11 @@ mapgen.shift_existing_biomes(NETHER_FLOOR, NETHER_CEILING)
|
||||
-- Ores and decorations can be registered against "nether:rack" instead, and the lua
|
||||
-- on_generate() callback will carve the Nether with nether:rack before invoking
|
||||
-- generate_decorations and generate_ores.
|
||||
minetest.register_node("nether:native_mapgen", {})
|
||||
-- It is disguised as stone to hide any bug where it leaks out of the nether, such as
|
||||
-- https://github.com/minetest/minetest/issues/13440 or if on_generated() somehow was aborted.
|
||||
local stone_copy_def = table.copy(minetest.registered_nodes["default:stone"] or {})
|
||||
stone_copy_def.drop = stone_copy_def.drop or "default:stone" -- probably already defined as cobblestone
|
||||
minetest.register_node("nether:native_mapgen", stone_copy_def)
|
||||
|
||||
minetest.register_biome({
|
||||
name = "nether_caverns",
|
||||
@ -283,6 +288,7 @@ local dbuf = {}
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_netherrack = minetest.get_content_id("nether:rack")
|
||||
local c_netherrack_deep = minetest.get_content_id("nether:rack_deep")
|
||||
local c_crystaldark = minetest.get_content_id("nether:geode")
|
||||
local c_lavasea_source = minetest.get_content_id("nether:lava_source") -- same as lava but with staggered animation to look better as an ocean
|
||||
local c_lava_crust = minetest.get_content_id("nether:lava_crust")
|
||||
local c_native_mapgen = minetest.get_content_id("nether:native_mapgen")
|
||||
@ -382,7 +388,8 @@ local function on_generated(minp, maxp, seed)
|
||||
if cave_noise > tcave then
|
||||
-- Prime region
|
||||
-- This was the only region in initial versions of the Nether mod.
|
||||
-- It is the only region which portals from the surface will open into.
|
||||
-- It is the only region which portals from the surface will open into,
|
||||
-- getting to any other regions in the Nether will require Shanks' Pony.
|
||||
data[vi] = c_air
|
||||
contains_nether = true
|
||||
|
||||
@ -392,12 +399,11 @@ local function on_generated(minp, maxp, seed)
|
||||
-- Reaching here would require the player to first find and journey through the central region,
|
||||
-- as it's always separated from the Prime region by the central region.
|
||||
|
||||
data[vi] = c_netherrack -- For now I've just left this region as solid netherrack instead of air.
|
||||
data[vi] = mapgen.getGeodeInteriorNodeId(x, y, z)-- function from mapgen_geodes.lua
|
||||
|
||||
-- Only set contains_nether to true here if you want tunnels created between the secondary region
|
||||
-- and the central region.
|
||||
--contains_nether = true
|
||||
--data[vi] = c_air
|
||||
contains_nether = true
|
||||
else
|
||||
-- netherrack walls and/or center region/mantle
|
||||
abs_cave_noise = math_abs(cave_noise)
|
||||
@ -414,7 +420,11 @@ local function on_generated(minp, maxp, seed)
|
||||
data[vi] = c_netherrack_deep
|
||||
else
|
||||
-- the shell seperating the mantle from the rest of the nether...
|
||||
data[vi] = c_netherrack -- excavate_dungeons() will mostly reverse this inside dungeons
|
||||
if cave_noise > 0 then
|
||||
data[vi] = c_netherrack -- excavate_dungeons() will mostly reverse this inside dungeons
|
||||
else
|
||||
data[vi] = c_crystaldark
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -33,6 +33,7 @@ minetest.set_gen_notify({dungeon = true})
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_netherrack = minetest.get_content_id("nether:rack")
|
||||
local c_netherrack_deep = minetest.get_content_id("nether:rack_deep")
|
||||
local c_crystaldark = minetest.get_content_id("nether:geode")
|
||||
local c_dungeonbrick = minetest.get_content_id("nether:brick")
|
||||
local c_dungeonbrick_alt = minetest.get_content_id("nether:brick_cracked")
|
||||
local c_netherbrick_slab = minetest.get_content_id("stairs:slab_nether_brick")
|
||||
@ -164,7 +165,7 @@ nether.mapgen.excavate_dungeons = function(data, area, rooms)
|
||||
vi = area:index(room_min.x, y, z)
|
||||
for x = room_min.x, room_max.x do
|
||||
node_id = data[vi]
|
||||
if node_id == c_netherrack or node_id == c_netherrack_deep then data[vi] = c_air end
|
||||
if node_id == c_netherrack or node_id == c_netherrack_deep or node_id == c_crystaldark then data[vi] = c_air end
|
||||
vi = vi + 1
|
||||
end
|
||||
end
|
||||
@ -181,7 +182,7 @@ nether.mapgen.excavate_dungeons = function(data, area, rooms)
|
||||
vi = vi + area.ystride
|
||||
node_id = data[vi]
|
||||
-- searching forward of the stairs could also be done
|
||||
if node_id == c_netherrack or node_id == c_netherrack_deep then data[vi] = c_air end
|
||||
if node_id == c_netherrack or node_id == c_netherrack_deep or node_id == c_crystaldark then data[vi] = c_air end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -231,11 +232,11 @@ nether.mapgen.decorate_dungeons = function(data, area, rooms)
|
||||
and room_min.z > minEdge.z and room_max.z < maxEdge.z then
|
||||
--data[area:indexp(roomInfo)] = minetest.get_content_id("default:mese_post_light") -- debug
|
||||
|
||||
-- Can't use glass panes because they need the param data set.
|
||||
-- Until whisper glass is added, every window will be made of netherbrick fence (rather
|
||||
-- than material depending on room_seed)
|
||||
-- Glass panes can't go in the windows because we aren't setting param data.
|
||||
-- Until a Nether glass is added, every window will be made of netherbrick fence rather
|
||||
-- than material depending on room_seed.
|
||||
local window_node = c_netherfence
|
||||
--if c_netherglass ~= nil and room_seed % 20 >= 12 then window_node = c_crystallight end
|
||||
--if c_netherglass ~= nil and room_seed % 20 >= 12 then window_node = c_netherglass end
|
||||
|
||||
local function placeWindow(vi, viOutsideOffset, windowNo)
|
||||
if is_dungeon_brick(data[vi]) and is_dungeon_brick(data[vi + yStride]) then
|
||||
|
221
mapgen_geodes.lua
Normal file
221
mapgen_geodes.lua
Normal file
@ -0,0 +1,221 @@
|
||||
--[[
|
||||
|
||||
Nether mod for minetest
|
||||
|
||||
This file contains helper functions for generating geode interiors,
|
||||
a proof-of-concept to demonstrate how the secondary/spare region
|
||||
in the nether might be put to use by someone.
|
||||
|
||||
|
||||
Copyright (C) 2021 Treer
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
]]--
|
||||
|
||||
|
||||
local debugf = nether.debug
|
||||
local mapgen = nether.mapgen
|
||||
|
||||
|
||||
-- Content ids
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_crystal = minetest.get_content_id("nether:geodelite") -- geodelite has a faint glow
|
||||
local c_netherrack = minetest.get_content_id("nether:rack")
|
||||
local c_glowstone = minetest.get_content_id("nether:glowstone")
|
||||
|
||||
-- Math funcs
|
||||
local math_max, math_min, math_abs, math_floor, math_pi = math.max, math.min, math.abs, math.floor, math.pi -- avoid needing table lookups each time a common math function is invoked
|
||||
|
||||
|
||||
-- Create a tiling space of close-packed spheres, using Hexagonal close packing
|
||||
-- of spheres with radius 0.5.
|
||||
-- With a layer of spheres on a flat surface, if the pack-z distance is 1 due to 0.5
|
||||
-- radius then the pack-x distance will be the height of an equilateral triangle: sqrt(3) / 2,
|
||||
-- and the pack-y distance between each layer will be sqrt(6) / 3,
|
||||
-- The tessellating space will be a rectangular box of 2*pack-x by 1*pack-z by 3*pack-y
|
||||
|
||||
local xPack = math.sqrt(3)/2 -- 0.866, height of an equalateral triangle
|
||||
local xPack2 = xPack * 2 -- 1.732
|
||||
local yPack = math.sqrt(6) / 3 -- 0.816, y height of each layer
|
||||
local yPack2 = yPack * 2
|
||||
local yPack3 = yPack * 3
|
||||
local layer2offsetx = xPack / 3 -- 0.289, height to center of equalateral triangle
|
||||
local layer3offsetx = xPack2 / 3 -- 0.577
|
||||
local structureSize = 50 -- magic numbers may need retuning if this changes too much
|
||||
|
||||
local layer1 = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 1},
|
||||
{xPack, 0, -0.5},
|
||||
{xPack, 0, 0.5},
|
||||
{xPack, 0, 1.5},
|
||||
{xPack2, 0, 0},
|
||||
{xPack2, 0, 1},
|
||||
}
|
||||
local layer2 = {
|
||||
{layer2offsetx - xPack, yPack, 0},
|
||||
{layer2offsetx - xPack, yPack, 1},
|
||||
{layer2offsetx, yPack, -0.5},
|
||||
{layer2offsetx, yPack, 0.5},
|
||||
{layer2offsetx, yPack, 1.5},
|
||||
{layer2offsetx + xPack, yPack, 0},
|
||||
{layer2offsetx + xPack, yPack, 1},
|
||||
{layer2offsetx + xPack2, yPack, -0.5},
|
||||
{layer2offsetx + xPack2, yPack, 0.5},
|
||||
{layer2offsetx + xPack2, yPack, 1.5},
|
||||
}
|
||||
local layer3 = {
|
||||
{layer3offsetx - xPack, yPack2, -0.5},
|
||||
{layer3offsetx - xPack, yPack2, 0.5},
|
||||
{layer3offsetx - xPack, yPack2, 1.5},
|
||||
{layer3offsetx, yPack2, 0},
|
||||
{layer3offsetx, yPack2, 1},
|
||||
{layer3offsetx + xPack, yPack2, -0.5},
|
||||
{layer3offsetx + xPack, yPack2, 0.5},
|
||||
{layer3offsetx + xPack, yPack2, 1.5},
|
||||
{layer3offsetx + xPack2, yPack2, 0},
|
||||
{layer3offsetx + xPack2, yPack2, 1},
|
||||
}
|
||||
local layer4 = {
|
||||
{0, yPack3, 0},
|
||||
{0, yPack3, 1},
|
||||
{xPack, yPack3, -0.5},
|
||||
{xPack, yPack3, 0.5},
|
||||
{xPack, yPack3, 1.5},
|
||||
{xPack2, yPack3, 0},
|
||||
{xPack2, yPack3, 1},
|
||||
}
|
||||
local layers = {
|
||||
{y = layer1[1][2], points = layer1}, -- layer1[1][2] is the y value of the first point in layer1, and all spheres in a layer have the same y
|
||||
{y = layer2[1][2], points = layer2},
|
||||
{y = layer3[1][2], points = layer3},
|
||||
{y = layer4[1][2], points = layer4},
|
||||
}
|
||||
|
||||
|
||||
-- Geode mapgen functions (AKA proof of secondary/spare region concept)
|
||||
|
||||
|
||||
-- fast for small lists
|
||||
function insertionSort(array)
|
||||
local i
|
||||
for i = 2, #array do
|
||||
local key = array[i]
|
||||
local j = i - 1
|
||||
while j > 0 and array[j] > key do
|
||||
array[j + 1] = array[j]
|
||||
j = j - 1
|
||||
end
|
||||
array[j + 1] = key
|
||||
end
|
||||
return array
|
||||
end
|
||||
|
||||
|
||||
local distSquaredList = {}
|
||||
local adj_x = 0
|
||||
local adj_y = 0
|
||||
local adj_z = 0
|
||||
local lasty, lastz
|
||||
local warpx, warpz
|
||||
|
||||
|
||||
-- It's quite a lot to calculate for each air node, but its not terribly slow and
|
||||
-- it'll be pretty darn rare for chunks in the secondary region to ever get emerged.
|
||||
mapgen.getGeodeInteriorNodeId = function(x, y, z)
|
||||
|
||||
if z ~= lastz then
|
||||
lastz = z
|
||||
-- Calculate structure warping
|
||||
-- To avoid calculating this for each node there's no warping as you look along the x axis :(
|
||||
adj_y = math.sin(math_pi / 222 * y) * 30
|
||||
|
||||
if y ~= lasty then
|
||||
lasty = y
|
||||
warpx = math.sin(math_pi / 100 * y) * 10
|
||||
warpz = math.sin(math_pi / 43 * y) * 15
|
||||
end
|
||||
local twistRadians = math_pi / 73 * y
|
||||
local sinTwist, cosTwist = math.sin(twistRadians), math.cos(twistRadians)
|
||||
adj_x = cosTwist * warpx - sinTwist * warpz
|
||||
adj_z = sinTwist * warpx + cosTwist * warpz
|
||||
end
|
||||
|
||||
-- convert x, y, z into a position in the tessellating space
|
||||
local cell_x = (((x + adj_x) / xPack2 + 0.5) % structureSize) / structureSize * xPack2
|
||||
local cell_y = (((y + adj_y) / yPack3 + 0.5) % structureSize) / structureSize * yPack3
|
||||
local cell_z = (((z + adj_z) + 0.5) % structureSize) / structureSize -- zPack = 1, so can be omitted
|
||||
|
||||
local iOut = 1
|
||||
local i, j
|
||||
local canSkip = false
|
||||
|
||||
for i = 1, #layers do
|
||||
|
||||
local layer = layers[i]
|
||||
local dy = cell_y - layer.y
|
||||
|
||||
if dy > -0.71 and dy < 0.71 then -- optimization - don't include points to far away to make a difference. (0.71 comes from sin(45°))
|
||||
local points = layer.points
|
||||
|
||||
for j = 1, #points do
|
||||
|
||||
local point = points[j]
|
||||
local dx = cell_x - point[1]
|
||||
local dz = cell_z - point[3]
|
||||
local distSquared = dx*dx + dy*dy + dz*dz
|
||||
|
||||
if distSquared < 0.25 then
|
||||
-- optimization - point is inside a sphere, so cannot be a wall edge. (0.25 comes from radius of 0.5 squared)
|
||||
return c_air
|
||||
end
|
||||
|
||||
distSquaredList[iOut] = distSquared
|
||||
iOut = iOut + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- clear the rest of the array instead of creating a new one to hopefully reduce luajit mem leaks.
|
||||
while distSquaredList[iOut] ~= nil do
|
||||
rawset(distSquaredList, iOut, nil)
|
||||
iOut = iOut + 1
|
||||
end
|
||||
|
||||
insertionSort(distSquaredList)
|
||||
|
||||
local d3_1 = distSquaredList[3] - distSquaredList[1]
|
||||
local d3_2 = distSquaredList[3] - distSquaredList[2]
|
||||
--local d4_1 = distSquaredList[4] - distSquaredList[1]
|
||||
--local d4_3 = distSquaredList[4] - distSquaredList[3]
|
||||
|
||||
-- Some shape formulas (tuned for a structureSize of 50)
|
||||
-- (d3_1 < 0.05) gives connective lines
|
||||
-- (d3_1 < 0.05 or d3_2 < .02) give fancy elven bridges - prob doesn't need the d3_1 part
|
||||
-- ((d3_1 < 0.05 or d3_2 < .02) and distSquaredList[1] > .3) tapers the fancy connections in the middle
|
||||
-- (d4_3 < 0.03 and d3_2 < 0.03) produces caltrops at intersections
|
||||
-- (d4_1 < 0.1) produces spherish balls at intersections
|
||||
-- The idea is voronoi based - edges in a voronoi diagram are where each nearby point is at equal distance.
|
||||
-- In this case we use squared distances to avoid calculating square roots.
|
||||
|
||||
if (d3_1 < 0.05 or d3_2 < .02) and distSquaredList[1] > .3 then
|
||||
return c_crystal
|
||||
elseif (distSquaredList[4] - distSquaredList[1]) < 0.08 then
|
||||
return c_glowstone
|
||||
else
|
||||
return c_air
|
||||
end
|
||||
end
|
2
mod.conf
2
mod.conf
@ -1,4 +1,4 @@
|
||||
name = nether
|
||||
description = Adds a deep underground realm with different mapgen that you can reach with obsidian portals.
|
||||
depends = stairs, default
|
||||
optional_depends = moreblocks, mesecons, loot, dungeon_loot, doc_basics, fire, climate_api, ethereal
|
||||
optional_depends = toolranks, moreblocks, mesecons, loot, dungeon_loot, doc_basics, fire, climate_api, ethereal, xpanes, walls
|
||||
|
302
nodes.lua
302
nodes.lua
@ -65,23 +65,186 @@ nether.register_wormhole_node("nether:portal_alt", {
|
||||
})
|
||||
|
||||
|
||||
--== Transmogrification functions ==--
|
||||
-- Functions enabling selected nodes to be temporarily transformed into other nodes.
|
||||
-- (so the light staff can temporarily turn netherrack into glowstone)
|
||||
|
||||
-- Swaps the node at `nodePos` with `newNode`, unless `newNode` is nil in which
|
||||
-- case the node is swapped back to its original type.
|
||||
-- `monoSimpleSoundSpec` is optional.
|
||||
-- returns true if a node was transmogrified
|
||||
nether.magicallyTransmogrify_node = function(nodePos, playerName, newNode, monoSimpleSoundSpec, isPermanent)
|
||||
|
||||
local meta = minetest.get_meta(nodePos)
|
||||
local playerEyePos = nodePos -- fallback value in case the player no longer exists
|
||||
local player = minetest.get_player_by_name(playerName)
|
||||
if player ~= nil then
|
||||
local playerPos = player:get_pos()
|
||||
playerEyePos = vector.add(playerPos, {x = 0, y = 1.5, z = 0}) -- not always the cameraPos, e.g. 3rd person mode.
|
||||
end
|
||||
|
||||
local oldNode = minetest.get_node(nodePos)
|
||||
if oldNode.name == "air" then
|
||||
-- the node has been mined or otherwise destroyed, abort the operation
|
||||
return false
|
||||
end
|
||||
local oldNodeDef = minetest.registered_nodes[oldNode.name] or minetest.registered_nodes["air"]
|
||||
|
||||
local specialFXSize = 1 -- a specialFXSize of 1 is for full SFX, 0.5 is half-sized
|
||||
local returningToNormal = newNode == nil
|
||||
if returningToNormal then
|
||||
-- This is the transmogrified node returning back to normal - a more subdued animation
|
||||
specialFXSize = 0.5
|
||||
-- read what the node used to be from the metadata
|
||||
newNode = {
|
||||
name = meta:get_string("transmogrified_name"),
|
||||
param1 = meta:get_string("transmogrified_param1"),
|
||||
param2 = meta:get_string("transmogrified_param2")
|
||||
}
|
||||
if newNode.name == "" then
|
||||
minetest.log("warning", "nether.magicallyTransmogrify_node() invoked to restore node which wasn't transmogrified")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local soundSpec = monoSimpleSoundSpec
|
||||
if soundSpec == nil and oldNodeDef.sounds ~= nil then
|
||||
soundSpec = oldNodeDef.sounds.dug or oldNodeDef.sounds.dig
|
||||
if soundSpec == "__group" then soundSpec = "default_dig_cracky" end
|
||||
end
|
||||
if soundSpec ~= nil then
|
||||
minetest.sound_play(soundSpec, {pos = nodePos, max_hear_distance = 50})
|
||||
end
|
||||
|
||||
-- Start the particlespawner nearer the player's side of the node to create
|
||||
-- more initial occlusion for an illusion of the old node breaking apart / falling away.
|
||||
local dirToPlayer = vector.normalize(vector.subtract(playerEyePos, nodePos))
|
||||
local impactPos = vector.add(nodePos, vector.multiply(dirToPlayer, 0.5))
|
||||
local velocity = 1 + specialFXSize
|
||||
minetest.add_particlespawner({
|
||||
amount = 50 * specialFXSize,
|
||||
time = 0.1,
|
||||
minpos = vector.add(impactPos, -0.3),
|
||||
maxpos = vector.add(impactPos, 0.3),
|
||||
minvel = {x = -velocity, y = -velocity, z = -velocity},
|
||||
maxvel = {x = velocity, y = 3 * velocity, z = velocity}, -- biased upward to counter gravity in the initial stages
|
||||
minacc = {x=0, y=-10, z=0},
|
||||
maxacc = {x=0, y=-10, z=0},
|
||||
minexptime = 1.5 * specialFXSize,
|
||||
maxexptime = 3 * specialFXSize,
|
||||
minsize = 0.5,
|
||||
maxsize = 5,
|
||||
node = {name = oldNodeDef.name},
|
||||
glow = oldNodeDef.light_source
|
||||
})
|
||||
|
||||
if returningToNormal or isPermanent then
|
||||
-- clear the metadata that indicates the node is transformed
|
||||
meta:set_string("transmogrified_name", "")
|
||||
meta:set_int("transmogrified_param1", 0)
|
||||
meta:set_int("transmogrified_param2", 0)
|
||||
else
|
||||
-- save the original node so it can be restored
|
||||
meta:set_string("transmogrified_name", oldNode.name)
|
||||
meta:set_int("transmogrified_param1", oldNode.param1)
|
||||
meta:set_int("transmogrified_param2", oldNode.param2)
|
||||
end
|
||||
|
||||
minetest.swap_node(nodePos, newNode)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
local function transmogrified_can_dig (pos, player)
|
||||
if minetest.get_meta(pos):get_string("transmogrified_name") ~= "" then
|
||||
-- This node was temporarily transformed into its current form
|
||||
-- revert it back, rather than allow the player to mine transmogrified nodes.
|
||||
local playerName = ""
|
||||
if player ~= nil then playerName = player:get_player_name() end
|
||||
nether.magicallyTransmogrify_node(pos, playerName)
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Nether nodes
|
||||
|
||||
minetest.register_node("nether:rack", {
|
||||
description = S("Netherrack"),
|
||||
tiles = {"nether_rack.png"},
|
||||
is_ground_content = true,
|
||||
groups = {cracky = 3, level = 2},
|
||||
-- setting workable_with_nether_tools reduces the wear on nether:pick_nether when mining this node
|
||||
groups = {cracky = 3, level = 2, workable_with_nether_tools = 3},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
-- Geode crystals can only be introduced by the biomes-based mapgen, since it requires the
|
||||
-- MT 5.0 world-align texture features.
|
||||
minetest.register_node("nether:geode", {
|
||||
description = S("Nether Beryl"),
|
||||
_doc_items_longdesc = S("Nether geode crystal, found lining the interior walls of Nether geodes"),
|
||||
tiles = {{
|
||||
name = "nether_geode.png",
|
||||
align_style = "world",
|
||||
scale = 4
|
||||
}},
|
||||
is_ground_content = true,
|
||||
groups = {cracky = 3, oddly_breakable_by_hand = 3, nether_crystal = 1},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
})
|
||||
|
||||
-- Nether Berylite is a Beryl that can seen in the dark, used to light up the internal structure
|
||||
-- of the geode, so to avoid player confusion we'll just have it drop plain Beryl, and have only
|
||||
-- plain Beryl in the creative inventory.
|
||||
minetest.register_node("nether:geodelite", {
|
||||
description = S("Nether Berylite"),
|
||||
_doc_items_longdesc = S("Nether geode crystal. A crystalline structure with faint glow found inside large Nether geodes"),
|
||||
tiles = {{
|
||||
name = "nether_geode.png",
|
||||
align_style = "world",
|
||||
scale = 4
|
||||
}},
|
||||
light_source = 2,
|
||||
drop = "nether:geode",
|
||||
is_ground_content = true,
|
||||
groups = {cracky = 3, oddly_breakable_by_hand = 3, nether_crystal = 1, not_in_creative_inventory = 1},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
})
|
||||
|
||||
if minetest.get_modpath("xpanes") and minetest.global_exists("xpanes") and xpanes.register_pane ~= nil then
|
||||
xpanes.register_pane("nether_crystal_pane", {
|
||||
description = S("Nether Crystal Pane"),
|
||||
textures = {
|
||||
{
|
||||
name = "nether_geode_glass.png",
|
||||
align_style = "world",
|
||||
scale = 2
|
||||
},
|
||||
"",
|
||||
"xpanes_edge_obsidian.png"
|
||||
},
|
||||
inventory_image = "([combine:32x32:-8,-8=nether_geode_glass.png:24,-8=nether_geode_glass.png:-8,24=nether_geode_glass.png:24,24=nether_geode_glass.png)^[resize:16x16^[multiply:#922^default_obsidian_glass.png",
|
||||
wield_image = "([combine:32x32:-8,-8=nether_geode_glass.png:24,-8=nether_geode_glass.png:-8,24=nether_geode_glass.png:24,24=nether_geode_glass.png)^[resize:16x16^[multiply:#922^default_obsidian_glass.png", use_texture_alpha = true,
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3},
|
||||
recipe = {
|
||||
{"group:nether_crystal", "group:nether_crystal", "group:nether_crystal"},
|
||||
{"group:nether_crystal", "group:nether_crystal", "group:nether_crystal"}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
-- Deep Netherrack, found in the mantle / central magma layers
|
||||
minetest.register_node("nether:rack_deep", {
|
||||
description = S("Deep Netherrack"),
|
||||
_doc_items_longdesc = S("Netherrack from deep in the mantle"),
|
||||
tiles = {"nether_rack_deep.png"},
|
||||
is_ground_content = true,
|
||||
groups = {cracky = 3, level = 2},
|
||||
-- setting workable_with_nether_tools reduces the wear on nether:pick_nether when mining this node
|
||||
groups = {cracky = 3, level = 2, workable_with_nether_tools = 3},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
@ -103,6 +266,7 @@ minetest.register_node("nether:glowstone", {
|
||||
paramtype = "light",
|
||||
groups = {cracky = 3, oddly_breakable_by_hand = 3},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
can_dig = transmogrified_can_dig, -- to ensure glowstone temporarily created by the lightstaff can't be kept
|
||||
})
|
||||
|
||||
-- Deep glowstone, found in the mantle / central magma layers
|
||||
@ -114,6 +278,7 @@ minetest.register_node("nether:glowstone_deep", {
|
||||
paramtype = "light",
|
||||
groups = {cracky = 3, oddly_breakable_by_hand = 3},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
can_dig = transmogrified_can_dig, -- to ensure glowstone temporarily created by the lightstaff can't be kept
|
||||
})
|
||||
|
||||
minetest.register_node("nether:brick", {
|
||||
@ -141,67 +306,131 @@ minetest.register_node("nether:brick_cracked", {
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("nether:brick_deep", {
|
||||
description = S("Deep Nether Brick"),
|
||||
tiles = {{
|
||||
name = "nether_brick_deep.png",
|
||||
align_style = "world",
|
||||
scale = 2
|
||||
}},
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 2, level = 2},
|
||||
sounds = default.node_sound_stone_defaults()
|
||||
})
|
||||
|
||||
-- Register fence and rails
|
||||
|
||||
local fence_texture =
|
||||
"default_fence_overlay.png^nether_brick.png^default_fence_overlay.png^[makealpha:255,126,126"
|
||||
|
||||
minetest.register_node("nether:fence_nether_brick", {
|
||||
local rail_texture =
|
||||
"default_fence_rail_overlay.png^nether_brick.png^default_fence_rail_overlay.png^[makealpha:255,126,126"
|
||||
|
||||
default.register_fence("nether:fence_nether_brick", {
|
||||
description = S("Nether Brick Fence"),
|
||||
drawtype = "fencelike",
|
||||
tiles = {"nether_brick.png"},
|
||||
texture = "nether_brick.png",
|
||||
inventory_image = fence_texture,
|
||||
wield_image = fence_texture,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
|
||||
},
|
||||
material = "nether:brick",
|
||||
groups = {cracky = 2, level = 2},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sounds = default.node_sound_stone_defaults()
|
||||
})
|
||||
|
||||
minetest.register_node("nether:brick_deep", {
|
||||
description = S("Deep Nether Brick"),
|
||||
tiles = {"nether_brick_deep.png"},
|
||||
is_ground_content = false,
|
||||
default.register_fence_rail("nether:fence_rail_nether_brick", {
|
||||
description = S("Nether Brick Fence Rail"),
|
||||
texture = "nether_brick.png",
|
||||
inventory_image = rail_texture,
|
||||
wield_image = rail_texture,
|
||||
material = "nether:brick",
|
||||
groups = {cracky = 2, level = 2},
|
||||
sounds = default.node_sound_stone_defaults()
|
||||
})
|
||||
|
||||
-- Register stair and slab
|
||||
|
||||
stairs.register_stair_and_slab(
|
||||
"nether_brick",
|
||||
"nether:brick",
|
||||
{cracky = 2, level = 2},
|
||||
{"nether_brick.png"},
|
||||
S("Nether Stair"),
|
||||
S("Nether Slab"),
|
||||
default.node_sound_stone_defaults(),
|
||||
nil,
|
||||
S("Inner Nether Stair"),
|
||||
S("Outer Nether Stair")
|
||||
-- Nether bricks can be made into stairs, slabs, inner stairs, and outer stairs
|
||||
|
||||
stairs.register_stair_and_slab( -- this function also registers inner and outer stairs
|
||||
"nether_brick", -- subname
|
||||
"nether:brick", -- recipeitem
|
||||
{cracky = 2, level = 2}, -- groups
|
||||
{"nether_brick.png"}, -- images
|
||||
S("Nether Stair"), -- desc_stair
|
||||
S("Nether Slab"), -- desc_slab
|
||||
minetest.registered_nodes["nether:brick"].sounds, -- sounds
|
||||
false, -- worldaligntex
|
||||
S("Inner Nether Stair"), -- desc_stair_inner
|
||||
S("Outer Nether Stair") -- desc_stair_outer
|
||||
)
|
||||
|
||||
stairs.register_stair_and_slab( -- this function also registers inner and outer stairs
|
||||
"nether_brick_deep", -- subname
|
||||
"nether:brick_deep", -- recipeitem
|
||||
{cracky = 2, level = 2}, -- groups
|
||||
{"nether_brick_deep.png"}, -- images
|
||||
S("Deep Nether Stair"), -- desc_stair
|
||||
S("Deep Nether Slab"), -- desc_slab
|
||||
minetest.registered_nodes["nether:brick_deep"].sounds, -- sounds
|
||||
false, -- worldaligntex
|
||||
S("Inner Deep Nether Stair"), -- desc_stair_inner
|
||||
S("Outer Deep Nether Stair") -- desc_stair_outer
|
||||
)
|
||||
|
||||
-- Netherrack can be shaped into stairs, slabs and walls
|
||||
|
||||
stairs.register_stair(
|
||||
"netherrack",
|
||||
"nether:rack",
|
||||
{cracky = 2, level = 2},
|
||||
{"nether_rack.png"},
|
||||
S("Netherrack stair"),
|
||||
default.node_sound_stone_defaults()
|
||||
S("Netherrack Stair"),
|
||||
minetest.registered_nodes["nether:rack"].sounds
|
||||
)
|
||||
stairs.register_slab( -- register a slab without adding inner and outer stairs
|
||||
"netherrack",
|
||||
"nether:rack",
|
||||
{cracky = 2, level = 2},
|
||||
{"nether_rack.png"},
|
||||
S("Netherrack Slab"),
|
||||
minetest.registered_nodes["nether:rack"].sounds
|
||||
)
|
||||
|
||||
stairs.register_stair(
|
||||
"netherrack_deep",
|
||||
"nether:rack_deep",
|
||||
{cracky = 2, level = 2},
|
||||
{"nether_rack_deep.png"},
|
||||
S("Deep Netherrack Stair"),
|
||||
minetest.registered_nodes["nether:rack_deep"].sounds
|
||||
)
|
||||
stairs.register_slab( -- register a slab without adding inner and outer stairs
|
||||
"netherrack_deep",
|
||||
"nether:rack_deep",
|
||||
{cracky = 2, level = 2},
|
||||
{"nether_rack_deep.png"},
|
||||
S("Deep Netherrack Slab"),
|
||||
minetest.registered_nodes["nether:rack_deep"].sounds
|
||||
)
|
||||
|
||||
-- Connecting walls
|
||||
if minetest.get_modpath("walls") and minetest.global_exists("walls") and walls.register ~= nil then
|
||||
walls.register("nether:rack_wall", S("A Netherrack Wall"), "nether_rack.png", "nether:rack", minetest.registered_nodes["nether:rack"].sounds)
|
||||
walls.register("nether:rack_deep_wall", S("A Deep Netherrack Wall"), "nether_rack_deep.png", "nether:rack_deep", minetest.registered_nodes["nether:rack_deep"].sounds)
|
||||
end
|
||||
|
||||
-- StairsPlus
|
||||
|
||||
if minetest.get_modpath("moreblocks") then
|
||||
-- Registers about 49 different shapes of nether brick, replacing the stairs & slabs registered above.
|
||||
-- (This could also be done for deep nether brick, but I've left that out to avoid a precedent of 49 new
|
||||
-- nodes every time the nether gets a new material. Nether structures won't be able to use them because
|
||||
-- they can't depend on moreblocks)
|
||||
stairsplus:register_all(
|
||||
"nether", "brick", "nether:brick", {
|
||||
description = S("Nether Brick"),
|
||||
groups = {cracky = 2, level = 2},
|
||||
tiles = {"nether_brick.png"},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
sounds = minetest.registered_nodes["nether:brick"].sounds,
|
||||
})
|
||||
end
|
||||
|
||||
@ -439,11 +668,11 @@ local function smash_lava_crust(pos, playsound)
|
||||
maxexptime = 1,
|
||||
minsize = .2,
|
||||
maxsize = .8,
|
||||
texture = "^[colorize:#A00:255",
|
||||
texture = "blank.png^[noalpha^[colorize:#A00:255",
|
||||
glow = 8
|
||||
}
|
||||
minetest.add_particlespawner(lava_particlespawn_def)
|
||||
lava_particlespawn_def.texture = "^[colorize:#FB0:255"
|
||||
lava_particlespawn_def.texture = "blank.png^[noalpha^[colorize:#FB0:255"
|
||||
lava_particlespawn_def.maxvel.y = 3
|
||||
lava_particlespawn_def.glow = 12
|
||||
minetest.add_particlespawner(lava_particlespawn_def)
|
||||
@ -549,6 +778,7 @@ minetest.register_node("nether:lava_crust", {
|
||||
--liquid_viscosity = 7,
|
||||
damage_per_second = 2,
|
||||
groups = {oddly_breakable_by_hand = 3, cracky = 3, explody = 1, igniter = 1},
|
||||
sounds = default.node_sound_gravel_defaults(),
|
||||
})
|
||||
|
||||
|
||||
@ -611,7 +841,7 @@ local function fumarole_onTimer(pos, elapsed)
|
||||
local smoke_time_adj = 1
|
||||
|
||||
local posAbove = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
local extinguish = minetest.get_node(posAbove).name ~= "air"
|
||||
local extinguish = inNether and minetest.get_node(posAbove).name ~= "air"
|
||||
|
||||
if extinguish or (canCatchFire and math.floor(elapsed) % 7 == 0) then
|
||||
|
||||
@ -644,11 +874,11 @@ local function fumarole_onTimer(pos, elapsed)
|
||||
maxexptime = 1.4,
|
||||
minsize = .2,
|
||||
maxsize = .8,
|
||||
texture = "^[colorize:#A00:255",
|
||||
texture = "blank.png^[noalpha^[colorize:#A00:255",
|
||||
glow = 8
|
||||
}
|
||||
minetest.add_particlespawner(embers_particlespawn_def)
|
||||
embers_particlespawn_def.texture = "^[colorize:#A50:255"
|
||||
embers_particlespawn_def.texture = "blank.png^[noalpha^[colorize:#A50:255"
|
||||
embers_particlespawn_def.maxvel.y = 3
|
||||
embers_particlespawn_def.glow = 12
|
||||
minetest.add_particlespawner(embers_particlespawn_def)
|
||||
|
@ -2166,22 +2166,20 @@ function nether.unregister_portal(name)
|
||||
end
|
||||
|
||||
function nether.register_portal_ignition_item(item_name, ignition_failure_sound)
|
||||
|
||||
local old_on_place = minetest.registered_items[item_name].on_place or minetest.item_place
|
||||
minetest.override_item(item_name, {
|
||||
on_place = function(stack, placer, pt)
|
||||
local done = false
|
||||
on_place = function(stack, placer, pt, ...)
|
||||
if pt.under and nether.is_frame_node[minetest.get_node(pt.under).name] then
|
||||
done = ignite_portal(pt.under, placer:get_player_name())
|
||||
local done = ignite_portal(pt.under, placer:get_player_name())
|
||||
if done and not minetest.settings:get_bool("creative_mode") then
|
||||
stack:take_item()
|
||||
end
|
||||
if not done and ignition_failure_sound ~= nil then
|
||||
minetest.sound_play(ignition_failure_sound, {pos = pt.under, max_hear_distance = 10})
|
||||
end
|
||||
return stack
|
||||
end
|
||||
if not done and ignition_failure_sound ~= nil then
|
||||
minetest.sound_play(ignition_failure_sound, {pos = pt.under, max_hear_distance = 10})
|
||||
end
|
||||
|
||||
|
||||
return stack
|
||||
return old_on_place(stack, placer, pt, ...)
|
||||
end,
|
||||
})
|
||||
|
||||
|
BIN
sounds/nether_lightstaff.ogg
Normal file
BIN
sounds/nether_lightstaff.ogg
Normal file
Binary file not shown.
BIN
sounds/nether_rack_destroy.ogg
Normal file
BIN
sounds/nether_rack_destroy.ogg
Normal file
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 198 B After Width: | Height: | Size: 765 B |
BIN
textures/nether_geode.png
Normal file
BIN
textures/nether_geode.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
textures/nether_geode_glass.png
Normal file
BIN
textures/nether_geode_glass.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 568 B |
BIN
textures/nether_lightstaff.png
Normal file
BIN
textures/nether_lightstaff.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
263
tools.lua
263
tools.lua
@ -20,18 +20,33 @@
|
||||
local S = nether.get_translator
|
||||
|
||||
minetest.register_tool("nether:pick_nether", {
|
||||
description = S("Nether Pickaxe"),
|
||||
description = S("Nether Pickaxe\nWell suited for mining netherrack"),
|
||||
_doc_items_longdesc = S("Uniquely suited for mining netherrack, with minimal wear when doing so. Blunts quickly on other materials."),
|
||||
inventory_image = "nether_tool_netherpick.png",
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 0.8,
|
||||
max_drop_level=3,
|
||||
groupcaps={
|
||||
cracky = {times={[1]=1.90, [2]=0.9, [3]=0.4}, uses=35, maxlevel=3},
|
||||
cracky = {times={[1]=1.90, [2]=0.9, [3]=0.3}, uses=35, maxlevel=2},
|
||||
},
|
||||
damage_groups = {fleshy=4},
|
||||
},
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
groups = {pickaxe = 1}
|
||||
groups = {pickaxe = 1},
|
||||
|
||||
after_use = function(itemstack, user, node, digparams)
|
||||
local wearDivisor = 1
|
||||
local nodeDef = minetest.registered_nodes[node.name]
|
||||
if nodeDef ~= nil and nodeDef.groups ~= nil then
|
||||
-- The nether pick hardly wears out when mining netherrack
|
||||
local workable = nodeDef.groups.workable_with_nether_tools or 0
|
||||
wearDivisor = 1 + (3 * workable) -- 10 for netherrack, 1 otherwise. Making it able to mine 350 netherrack nodes, instead of 35.
|
||||
end
|
||||
|
||||
local wear = math.floor(digparams.wear / wearDivisor)
|
||||
itemstack:add_wear(wear) -- apply the adjusted wear as usual
|
||||
return itemstack
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_tool("nether:shovel_nether", {
|
||||
@ -136,3 +151,245 @@ minetest.register_craft({
|
||||
{"group:stick"}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
if minetest.get_modpath("toolranks") then
|
||||
|
||||
local function add_toolranks(name)
|
||||
local nethertool_after_use = ItemStack(name):get_definition().after_use
|
||||
toolranks.add_tool(name)
|
||||
local toolranks_after_use = ItemStack(name):get_definition().after_use
|
||||
|
||||
if nethertool_after_use == nil or nethertool_after_use == toolranks_after_use then
|
||||
return
|
||||
end
|
||||
|
||||
minetest.override_item(name, {
|
||||
after_use = function(itemstack, user, node, digparams)
|
||||
-- combine nethertool_after_use and toolranks_after_use by allowing
|
||||
-- nethertool_after_use() to calculate the wear...
|
||||
local initial_wear = itemstack:get_wear()
|
||||
itemstack = nethertool_after_use(itemstack, user, node, digparams)
|
||||
local wear = itemstack:get_wear() - initial_wear
|
||||
itemstack:set_wear(initial_wear) -- restore/undo the wear
|
||||
|
||||
-- ...and have toolranks_after_use() apply the wear.
|
||||
digparams.wear = wear
|
||||
return toolranks_after_use(itemstack, user, node, digparams)
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
add_toolranks("nether:pick_nether")
|
||||
add_toolranks("nether:shovel_nether")
|
||||
add_toolranks("nether:axe_nether")
|
||||
add_toolranks("nether:sword_nether")
|
||||
end
|
||||
|
||||
|
||||
--===========================--
|
||||
--== Nether Staff of Light ==--
|
||||
--===========================--
|
||||
|
||||
nether.lightstaff_recipes = {
|
||||
["nether:rack"] = "nether:glowstone",
|
||||
["nether:brick"] = "nether:glowstone",
|
||||
["nether:brick_cracked"] = "nether:glowstone",
|
||||
["nether:brick_compressed"] = "nether:glowstone",
|
||||
["stairs:slab_netherrack"] = "nether:glowstone",
|
||||
["nether:rack_deep"] = "nether:glowstone_deep",
|
||||
["nether:brick_deep"] = "nether:glowstone_deep",
|
||||
["stairs:slab_netherrack_deep"] = "nether:glowstone_deep"
|
||||
}
|
||||
nether.lightstaff_range = 100
|
||||
nether.lightstaff_velocity = 60
|
||||
nether.lightstaff_gravity = 0 -- using 0 instead of 10 because projectile arcs look less magical - magic isn't affected by gravity ;) (but set this to 10 if you're making a crossbow etc.)
|
||||
nether.lightstaff_uses = 60 -- number of times the Eternal Lightstaff can be used before wearing out
|
||||
nether.lightstaff_duration = 40 -- lifespan of glowstone created by the termporay Lightstaff
|
||||
|
||||
-- 'serverLag' is a rough amount to reduce the projected impact-time the server must wait before initiating the
|
||||
-- impact events (i.e. node changing to glowstone with explosion particle effect).
|
||||
-- In tests using https://github.com/jagt/clumsy to simulate network lag I've found this value to not noticeably
|
||||
-- matter. A large network lag is noticeable in the time between clicking fire and when the shooting-particleEffect
|
||||
-- begins, as well as the time between when the impact sound/particleEffect start and when the netherrack turns
|
||||
-- into glowstone. The synchronization that 'serverLag' adjusts seems to already tolerate network lag well enough (at
|
||||
-- least when lag is consistent, as I have not simulated random lag)
|
||||
local serverLag = 0.05 -- in seconds. Larger values makes impact events more premature/early.
|
||||
|
||||
-- returns a pointed_thing, or nil if no solid node intersected the ray
|
||||
local function raycastForSolidNode(rayStartPos, rayEndPos)
|
||||
|
||||
local raycast = minetest.raycast(
|
||||
rayStartPos,
|
||||
rayEndPos,
|
||||
false, -- objects - if false, only nodes will be returned. Default is `true`
|
||||
true -- liquids - if false, liquid nodes won't be returned. Default is `false`
|
||||
)
|
||||
local next_pointed = raycast:next()
|
||||
while next_pointed do
|
||||
local under_node = minetest.get_node(next_pointed.under)
|
||||
local under_def = minetest.registered_nodes[under_node.name]
|
||||
|
||||
if (under_def and not under_def.buildable_to) or not under_def then
|
||||
return next_pointed
|
||||
end
|
||||
|
||||
next_pointed = raycast:next(next_pointed)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Turns a node into a light source
|
||||
-- `lightDuration` 0 is considered permanent, lightDuration is in seconds
|
||||
-- returns true if a node is transmogrified into a glowstone
|
||||
local function light_node(pos, playerName, lightDuration)
|
||||
|
||||
local result = false
|
||||
if minetest.is_protected(pos, playerName) then
|
||||
minetest.record_protection_violation(pos, playerName)
|
||||
return false
|
||||
end
|
||||
|
||||
local oldNode = minetest.get_node(pos)
|
||||
local litNodeName = nether.lightstaff_recipes[oldNode.name]
|
||||
|
||||
if litNodeName ~= nil then
|
||||
result = nether.magicallyTransmogrify_node(
|
||||
pos,
|
||||
playerName,
|
||||
{name=litNodeName},
|
||||
{name = "nether_rack_destroy", gain = 0.8},
|
||||
lightDuration == 0 -- isPermanent
|
||||
)
|
||||
|
||||
if lightDuration > 0 then
|
||||
minetest.after(lightDuration,
|
||||
function()
|
||||
-- Restore the node to its original type.
|
||||
--
|
||||
-- If the server crashes or shuts down before this is invoked, the node
|
||||
-- will remain in its transmogrified state. These could be cleaned up
|
||||
-- with an LBM, but I don't think that's necessary: if this functionality
|
||||
-- is only being used for the Nether Lightstaff then I don't think it
|
||||
-- matters if there's occasionally an extra glowstone left in the
|
||||
-- netherrack.
|
||||
nether.magicallyTransmogrify_node(pos, playerName)
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- a lightDuration of 0 is considered permanent, lightDuration is in seconds
|
||||
-- returns true if a node is transmogrified into a glowstone
|
||||
local function lightstaff_on_use(user, boltColorString, lightDuration)
|
||||
|
||||
if not user then return false end
|
||||
local playerName = user:get_player_name()
|
||||
local playerlookDir = user:get_look_dir()
|
||||
local playerPos = user:get_pos()
|
||||
local playerEyePos = vector.add(playerPos, {x = 0, y = 1.5, z = 0}) -- not always the cameraPos, e.g. 3rd person mode.
|
||||
local target = vector.add(playerEyePos, vector.multiply(playerlookDir, nether.lightstaff_range))
|
||||
|
||||
local targetHitPos = nil
|
||||
local targetNodePos = nil
|
||||
local target_pointed = raycastForSolidNode(playerEyePos, target)
|
||||
if target_pointed then
|
||||
targetNodePos = target_pointed.under
|
||||
targetHitPos = vector.divide(vector.add(target_pointed.under, target_pointed.above), 2)
|
||||
end
|
||||
|
||||
local wieldOffset = {x= 0.5, y = -0.2, z= 0.8}
|
||||
local lookRotation = ({x = -user:get_look_vertical(), y = user:get_look_horizontal(), z = 0})
|
||||
local wieldPos = vector.add(playerEyePos, vector.rotate(wieldOffset, lookRotation))
|
||||
local aimPos = targetHitPos or target
|
||||
local distance = math.abs(vector.length(vector.subtract(aimPos, wieldPos)))
|
||||
local flightTime = distance / nether.lightstaff_velocity
|
||||
local dropDistance = nether.lightstaff_gravity * 0.5 * (flightTime * flightTime)
|
||||
aimPos.y = aimPos.y + dropDistance
|
||||
local boltDir = vector.normalize(vector.subtract(aimPos, wieldPos))
|
||||
|
||||
minetest.sound_play("nether_lightstaff", {to_player = playerName, gain = 0.8}, true)
|
||||
|
||||
-- animate a "magic bolt" from wieldPos to aimPos
|
||||
local particleSpawnDef = {
|
||||
amount = 20,
|
||||
time = 0.4,
|
||||
minpos = vector.add(wieldPos, -0.13),
|
||||
maxpos = vector.add(wieldPos, 0.13),
|
||||
minvel = vector.multiply(boltDir, nether.lightstaff_velocity - 0.3),
|
||||
maxvel = vector.multiply(boltDir, nether.lightstaff_velocity + 0.3),
|
||||
minacc = {x=0, y=-nether.lightstaff_gravity, z=0},
|
||||
maxacc = {x=0, y=-nether.lightstaff_gravity, z=0},
|
||||
minexptime = 1,
|
||||
maxexptime = 2,
|
||||
minsize = 4,
|
||||
maxsize = 5,
|
||||
collisiondetection = true,
|
||||
collision_removal = true,
|
||||
texture = "nether_particle_anim3.png",
|
||||
animation = { type = "vertical_frames", aspect_w = 7, aspect_h = 7, length = 0.8 },
|
||||
glow = 15
|
||||
}
|
||||
minetest.add_particlespawner(particleSpawnDef)
|
||||
particleSpawnDef.texture = "nether_particle_anim3.png^[colorize:" .. boltColorString .. ":alpha"
|
||||
particleSpawnDef.amount = 12
|
||||
particleSpawnDef.time = 0.2
|
||||
particleSpawnDef.minsize = 6
|
||||
particleSpawnDef.maxsize = 7
|
||||
particleSpawnDef.minpos = vector.add(wieldPos, -0.35)
|
||||
particleSpawnDef.maxpos = vector.add(wieldPos, 0.35)
|
||||
minetest.add_particlespawner(particleSpawnDef)
|
||||
|
||||
local result = false
|
||||
if targetNodePos then
|
||||
-- delay the impact until roughly when the particle effects will have reached the target
|
||||
minetest.after(
|
||||
math.max(0, (distance / nether.lightstaff_velocity) - serverLag),
|
||||
function()
|
||||
light_node(targetNodePos, playerName, lightDuration)
|
||||
end
|
||||
)
|
||||
|
||||
if lightDuration ~= 0 then
|
||||
-- we don't need to care whether the transmogrify will be successful
|
||||
result = true
|
||||
else
|
||||
-- check whether the transmogrify will be successful
|
||||
local targetNode = minetest.get_node(targetNodePos)
|
||||
result = nether.lightstaff_recipes[targetNode.name] ~= nil
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- Inspired by FaceDeer's torch crossbow and Xanthin's Staff of Light
|
||||
minetest.register_tool("nether:lightstaff", {
|
||||
description = S("Nether staff of Light\nTemporarily transforms the netherrack into glowstone"),
|
||||
inventory_image = "nether_lightstaff.png",
|
||||
wield_image = "nether_lightstaff.png",
|
||||
light_source = 11, -- used by wielded_light mod etc.
|
||||
stack_max = 1,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
lightstaff_on_use(user, "#F70", nether.lightstaff_duration)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_tool("nether:lightstaff_eternal", {
|
||||
description = S("Nether staff of Eternal Light\nCreates glowstone from netherrack"),
|
||||
inventory_image = "nether_lightstaff.png^[colorize:#55F:90",
|
||||
wield_image = "nether_lightstaff.png^[colorize:#55F:90",
|
||||
light_source = 11, -- used by wielded_light mod etc.
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
stack_max = 1,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if lightstaff_on_use(user, "#23F", 0) -- was "#8088FF" or "#13F"
|
||||
and not minetest.is_creative_enabled(user) then
|
||||
-- The staff of Eternal Light wears out, to limit how much
|
||||
-- a player can alter the nether with it.
|
||||
itemstack:add_wear_by_uses(nether.lightstaff_uses)
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
})
|
||||
|
Reference in New Issue
Block a user