commit 6d30d4d8541ce329c6cc02963145796cbe5f6a29 Author: OldCoder Date: Sun Sep 4 22:03:00 2022 -0700 Imported from trollstream "ContentDB" diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8f5b16b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,24 @@ +Changelog +========= + +The semantic of version number is 'Major.minor'. Minor updates are retro-compatible, while major updates may break things. + +[0.2] - 2021-08-08 +------------------ + +### Added +- Secondary use of digging tools to trigger shape updates. + +### Changed +- Slopes are not listed in the creative inventory anymore. +- Dirt slopes were removed due to some palette limitations. + +### Fixed +- Texture alignment for rotated slopes. +- Warnings about transparent textures. + + +[0.1] - 2021-02-08 +------------------ + +Initial release. diff --git a/README.md b/README.md new file mode 100644 index 0000000..379ce28 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +Natural slopes for Hades Revisited +================================== + +* Version 0.2 + +Smoothen the edges by adding natural slopes at generation time and when the landscape changes for Hades Revisited. Most of the default ground nodes can have their "stair" shape which is set automatically when they are put on edges. + +Those slopes are not craftable, they just happen by themselves at generation time and when the landscape changes. You can also use your digging tools to soften the edges with their secondary use. This will wear the tool a little on success, and works better with higher-grade tools. + +This mod is an usage of naturalslopeslib for Hades Revisited. Please check the library page for the forum topic and details about its settings and optional dependencies. + +## Dependencies + +* Made with Hades Revisited 0.11.0 +* Requires naturalslopeslib 1.3 or above + +## Source code + +* Licenced under LGPLv2 or, at your discretion, any later version. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +https://www.gnu.org/licenses/licenses.html#LGPL diff --git a/dirt.lua b/dirt.lua new file mode 100644 index 0000000..6e11ae7 --- /dev/null +++ b/dirt.lua @@ -0,0 +1,45 @@ +local hadesS = minetest.get_translator("hade_core") +local translator = minetest.get_translator("minetestgame_slopes") +local S = function(name) + return translator("@1 Slope", hadesS(name)) +end +local S2 = function(name, l) + return translator("@1 Slope", hadesS(name, l)) +end + +naturalslopeslib.register_slope("hades_core:dirt", { + description = S("Dirt"), + }, + 30 +) + +-- Dirt with grass uses an other group because the original ABM erases param2 with a color +-- Those ABM are copied with the other group to be able to manage a colorfacedir + +-- ... with grass cover +naturalslopeslib.register_slope("hades_core:dirt_with_grass", { + description = S("Dirt with Grass"), + tiles = {"hades_core_grass_cover_colorable.png"}, + palette = "ns_hades_palette_grass.png", + overlay_tiles = "nil", + groups = {crumbly=3,soil=1,dirt=1,dirt_with_grass_slope=1, porous=1}, + }, + 40 +) + +-- Intermediate grass growth levels +for l=1, 3 do + naturalslopeslib.register_slope("hades_core:dirt_with_grass_l"..l, { + description = S2("Dirt with Growing Grass (Stage @1)", l), + overlay_tiles = { + {name="hades_core_grass_cover_colorable.png^[mask:hades_core_grass_mask_l"..l..".png", align_style="world"}, + "", +{name="hades_core_grass_cover_colorable.png^[mask:hades_core_grass_mask_l"..l..".png", align_style="world"}, + }, + palette = "ns_hades_palette_grass.png", + groups = {crumbly=3,soil=1,dirt=1,dirt_with_grass_slope=l+1, porous=1}, + }, + 35 + ) +end + diff --git a/functions.lua b/functions.lua new file mode 100644 index 0000000..9ac783e --- /dev/null +++ b/functions.lua @@ -0,0 +1,341 @@ +-- +-- Stone transformation +-- + +local function get_transformed_node(origin_name, base_dest) + local shape = minetest.get_item_group(origin_name, "natural_slope") + local dest_shapes = naturalslopeslib.get_all_shapes(base_dest) + if #dest_shapes > 1 then + return dest_shapes[shape + 1] + end + return base_dest +end + +minetest.register_abm({ + label = "Burn stone", + nodenames = {"group:family:hades_core:stone", "group:family:hades_core:mossystone"}, + neighbors = {"group:lava"}, + interval = 25, + chance = 15, + action = function(pos, node) + local nn + local block_name = naturalslopeslib.get_regular_node_name(node.name) + if block_name == "hades_core:mossystone" then + nn = "hades_core:stone" + else + nn = "hades_core:stone_baked" + end + nn = get_transformed_node(node.name, nn) + minetest.set_node(pos, {name=nn, param2=node.param2}) + end, +}) + +minetest.register_abm({ + label = "Create mossy stone", + nodenames = {"group:family:hades_core:stone"}, + interval = 600, + chance = 65, + action = function(pos, node) + if minetest.find_node_near(pos, 2, {"group:water"}) == nil then + return + else + local nn = get_transformed_node(node.name, "hades_core:mossystone") + minetest.set_node(pos, {name=nn, param2=node.param2}) + end + end, +}) + +-- +-- Tuff transformation +-- + +minetest.register_abm({ + label = "Burn tuff", + nodenames = {"group:family:hades_core:tuff", "group:family:hades_core:mossytuff"}, + neighbors = {"group:lava"}, + interval = 25, + chance = 15, + action = function(pos, node) + local shape = minetest.get_item_group(node.name, "natural_slope") + local nn = "hades_core:tuff_baked" + if minetest.get_item_group(node.name, "family:hades_core:mossytuff") then + local nn = get_transformed_node(node.name, "hades_core:tuff") + minetest.set_node(pos, {name=nn, param2=node.param2}) + else + local nn = get_transformed_node(node.name, "hades_core:tuff_baked") + minetest.set_node(pos, {name=nn, param2=node.param2}) + end + end, +}) + +minetest.register_abm({ + label = "Grow moss on tuff", + nodenames = {"group:family:hades_core:tuff"}, + interval = 600, + chance = 65, + action = function(pos, node) + if minetest.find_node_near(pos, 2, {"group:water"}) == nil then + return + else + local nn = get_transformed_node(node.name, "hades_core:mossytuff") + minetest.set_node(pos, {name=nn, param2=node.param2}) + end + end, +}) + +minetest.register_abm({ + label = "Create marble", + nodenames = {"group:family:hades_core:chondrite"}, + neighbors = {"group:water"}, + interval = 171, + chance = 55, + action = function(pos, node) + if minetest.find_node_near(pos, 4, {"group:lava"}) == nil or pos.y > -500 then + return + else + local nn = get_transformed_node(node.name, "hades_core:marble") + minetest.set_node(pos, {name=nn, param2=node.param2}) + end + end, +}) + +minetest.register_abm({ + label = "Create obsidian", + nodenames = {"group:family:hades_core:gravel_volcanic"}, + neighbors = {"group:lava"}, + interval = 180, + chance = 65, + action = function(pos, node) + if minetest.find_node_near(pos, 4, {"group:water"}) == nil or pos.y > -1000 then + return + else + minetest.set_node(pos, {name="hades_core:obsidian"}) + end + end, +}) + +-- +-- Cobble transformation +-- + +minetest.register_abm({ + label = "Grow moss on cobblestone (neighboring water)", + nodenames = {"group:family:hades_core:cobble"}, + neighbors = {"group:water"}, + interval = 500, + chance = 35, + action = function(pos, node) + local nn = get_transformed_node(node.name, "hades_core:mossycobble") + minetest.set_node(pos, {name=nn, param2=node.param2}) + end, +}) + +minetest.register_abm({ + label = "Grow moss on cobblestone (extended water check)", + nodenames = {"group:family:hades_core:cobble"}, + interval = 500, + chance = 55, + action = function(pos, node) + if minetest.find_node_near(pos, 2, {"group:water"}) == nil then + return + else + local nn = get_transformed_node(node.name, "hades_core:mossycobble") + minetest.set_node(pos, {name=nn, param2=node.param2}) + end + end, +}) + +minetest.register_abm({ + label = "Burn cobblestone", + nodenames = {"group:family:hades_core:cobble", "group:family:hades_core:mossycobble"}, + neighbors = {"group:lava"}, + interval = 45, + chance = 15, + action = function(pos, node) + local nn + local shape = minetest.get_item_group("natural_slope") + if node.name == "hades_core:mossycobble" then + nn = get_transformed_node(node.name, "hades_core:cobble") + else + nn = get_transformed_node(node.name, "hades_core:cobble_baked") + end + minetest.set_node(pos, {name=nn, param2=node.param2}) + end, +}) + +minetest.register_abm({ + label = "Create gravel near water", + nodenames = {"group:family:hades_core:mossycobble"}, + neighbors = {"hades_core:water_flowing"}, + interval = 500, + chance = 75, + action = function(pos, node) + local nn = get_transformed_node(node.name, "hades_core:gravel") + minetest.set_node(pos, {name=nn, param2=node.param2}) + end, +}) + +-- +-- Ash transformation +-- + +minetest.register_abm({ + label = "Create fertile sand", + nodenames = {"group:ash_fertilizer"}, -- used by most leaves + interval = 60, + chance = 390, -- this is increased because there is now 2 ABMs for transformation + action = function(pos, node) + local d = minetest.get_item_group(node.name, "ash_fertilizer") + local pos1 = vector.add(pos, {x=d ,y=-1, z=d}) + local pos2 = vector.add(pos, {x=-d, y=-d*2, z=-d}) + -- Turn ash to fertile sand + local ashes = minetest.find_nodes_in_area(pos1, pos2, {"group:family:hades_core:ash"}) + if #ashes == 0 then + return + end + local ash = ashes[math.random(1, #ashes)] + local ash_node = minetest.get_node({x=ash.x,y=ash.y,z=ash.z}) + local above_ash = minetest.get_node({x=ash.x,y=ash.y+1,z=ash.z}) + local aname = above_ash.name + local def = minetest.registered_nodes[aname] + if def and def.walkable then + return + end + local nn = get_transformed_node(ash_node.name, "hades_core:fertile_sand") + minetest.set_node(ash, {name=nn, param2=ash_node.param2}) + end, +}) + +-- +-- Fertile sand transformation +-- + +minetest.register_abm({ + label = "Create dirt (direct neighboring water)", + nodenames = {"group:family:hades_core:fertile_sand"}, + neighbors = {"group:water"}, + interval = 25, + chance = 5, + action = function(pos, node) + local nn = get_transformed_node(node.name, "hades_core:dirt") + minetest.set_node(pos, {name=nn, param2=node.param2}) + end, +}) + +minetest.register_abm({ + label = "Create dirt (extended water check)", + nodenames = {"group:family:hades_core:fertile_sand"}, + neighbors = {"hades_core:dirt", "hades_core:dirt_with_grass"}, + interval = 50, + chance = 5, + action = function(pos, node) + if minetest.find_node_near(pos, 10, {"group:water"}) == nil then + return + else + local nn = get_transformed_node(node.name, "hades_core:dirt") + minetest.set_node(pos, {name=nn, param2=node.param2}) + end + end, +}) + +-- +-- Dirt transformation +-- + +-- Takes a node name and if it's capable of being covered by grass, +-- returns the node name of the next level of "grassiness", +-- otherwise it returns nil +-- Override to use the same function for slopes and blocks +function hades_core.get_next_grass_cover_level(nodename) + local replacements = naturalslopeslib.get_replacement(nodename) + local base_nodename = nodename + local slope_group = minetest.get_item_group(nodename, "natural_slope") + if replacements then + base_nodename = replacements.source + end + local new_node + if base_nodename == "hades_core:dirt" then + new_node = "hades_core:dirt_with_grass_l1" + elseif base_nodename == "hades_core:dirt_with_grass_l1" then + new_node = "hades_core:dirt_with_grass_l2" + elseif base_nodename == "hades_core:dirt_with_grass_l2" then + new_node = "hades_core:dirt_with_grass_l3" + elseif base_nodename == "hades_core:dirt_with_grass_l3" then + new_node = "hades_core:dirt_with_grass" + end + if new_node then + if slope_group > 0 then + return naturalslopeslib.get_all_shapes(new_node)[slope_group + 1] + else + return new_node + end + end +end + +-- Dirt-with-Grass ABMs +-- This one has no changes, slopes can keep their param2 when growing and get_next_grass_cover_level now returns the next sloped node. +minetest.register_abm({ + label = "Increase Dirt-with-Grass-Slope grass level on Dirt-with-Grass-Slope under bright light", + nodenames = {"group:dirt_with_grass_slope"}, + interval = 2, + chance = 200, + action = function(pos, node) + local above = {x=pos.x, y=pos.y+1, z=pos.z} + local name = minetest.get_node(above).name + local nodedef = minetest.registered_nodes[name] + if nodedef and (nodedef.sunlight_propagates or nodedef.paramtype == "light") + and nodedef.liquidtype == "none" + and (minetest.get_node_light(above) or 0) >= 13 then + local nextnode = hades_core.get_next_grass_cover_level(node.name) + if nextnode then + minetest.set_node(pos, {name = nextnode, param2 = node.param2}) + end + end + end +}) + +-- No change either, same as above +minetest.register_abm({ + label = "Increase Dirt-with-Grass-Slope level on Dirt-with-Grass-Slope under air in faint light", + nodenames = {"group:dirt_with_grass_slope"}, + interval = 50, + chance = 20, + action = function(pos, node) + local name = minetest.get_node(pos).name + local node = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) + if node.name == "air" and (minetest.get_node_light(pos) or 0) >= 8 then + local nextnode = hades_core.get_next_grass_cover_level(node.name) + if nextnode then + minetest.set_node(pos, {name = nextnode, param2 = node.param2}) + end + end + end, +}) + +-- Updated to use new color as a colorfacedir instead of a color value +-- and revert to sloped dirt +minetest.register_abm({ + label = "Turn covered 'dirt with grass slope' back to dirt, update seasonal grass color", + nodenames = {"group:dirt_with_grass_slope"}, + interval = 2, + chance = 20, + action = function(pos, node) + local above = {x=pos.x, y=pos.y+1, z=pos.z} + local name = minetest.get_node(above).name + local nodedef = minetest.registered_nodes[name] + if name ~= "ignore" and nodedef + and not ((nodedef.sunlight_propagates or nodedef.paramtype == "light") + and nodedef.liquidtype == "none") then + local slope_group = minetest.get_item_group(node.name, "natural_slope") + local nextnode = naturalslopeslib.get_all_shapes("hades_core:dirt")[slope_group + 1] + minetest.set_node(pos, {name = nextnode, param2 = node.param2}) + else + local old_color = math.floor(node.param2 / 32) + local new_color = hades_core.get_seasonal_grass_color_param2(old_color) % 8 + if new_color ~= old_color then + local new_param2 = (node.param2 % 32) + (new_color * 32) + minetest.set_node(pos, {name = node.name, param2 = new_param2}) + end + end + end +}) diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..e107510 --- /dev/null +++ b/init.lua @@ -0,0 +1,18 @@ +--[[ +Add natural slopes to Minetest Game +--]] +local path = minetest.get_modpath(minetest.get_current_modname()) +dofile(path .."/functions.lua") + +naturalslopeslib.default_definition.drop_source = true +naturalslopeslib.default_definition.tiles = {{align_style = "world"}} +naturalslopeslib.default_definition.groups = {not_in_creative_inventory = 1} +naturalslopeslib.default_definition.use_texture_alpha = "clip" + +dofile(path .."/simple_nodes.lua") +dofile(path .."/leaves.lua") +dofile(path .."/dirt.lua") + +naturalslopeslib.reset_defaults() + +dofile(path .."/tools.lua") diff --git a/leaves.lua b/leaves.lua new file mode 100644 index 0000000..c3d0a09 --- /dev/null +++ b/leaves.lua @@ -0,0 +1,49 @@ +local S = minetest.get_translator("hade_core") + +naturalslopeslib.register_slope("hades_trees:banana_leaves", { + description = S("Banana Leaves Slope"), + }, + 10 +) + +naturalslopeslib.register_slope("hades_trees:birch_leaves", { + description = S("Birch Leaves Slope"), + }, + 10 +) + +naturalslopeslib.register_slope("hades_trees:cultivated_jungle_leaves", { + description = S("Cultivated Jungle Leaves Slope"), + }, + 10 +) + +naturalslopeslib.register_slope("hades_trees:leaves", { + description = S("Common Leaves Slope"), + }, + 10 +) + +naturalslopeslib.register_slope("hades_trees:jungle_leaves", { + description = S("Jungle Leaves Slope"), + }, + 10 +) + +naturalslopeslib.register_slope("hades_trees:olive_leaves", { + description = S("Olive Leaves Slope"), + }, + 10 +) + +naturalslopeslib.register_slope("hades_trees:orange_leaves", { + description = S("Orange Leaves Slope"), + }, + 10 +) + +naturalslopeslib.register_slope("hades_trees:pale_leaves", { + description = S("Pale Leaves Slope"), + }, + 10 +) diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..1115532 --- /dev/null +++ b/mod.conf @@ -0,0 +1,3 @@ +description = Add ground slopes for Hades Revisited +depends = naturalslopeslib, hades_core, hades_trees +optional_depends = hades_farming diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..4da51d6 Binary files /dev/null and b/screenshot.png differ diff --git a/simple_nodes.lua b/simple_nodes.lua new file mode 100644 index 0000000..2c890c7 --- /dev/null +++ b/simple_nodes.lua @@ -0,0 +1,114 @@ +local hadesS = minetest.get_translator("hade_core") +local translator = minetest.get_translator("minetestgame_slopes") +local S = function(name) + return translator("@1 Slope", hadesS(name)) +end + +naturalslopeslib.register_slope("hades_core:stone", { + description = S("Stone"), + }, + 100 +) + +naturalslopeslib.register_slope("hades_core:mossystone", { + description = S("Mossy Stone"), + }, + 100 +) + +naturalslopeslib.register_slope("hades_core:chondrite", { + description = S("Chondrite"), + }, + 60 +) + +naturalslopeslib.register_slope("hades_core:tuff", { + description = S("Tuff"), + }, + 80 +) + +naturalslopeslib.register_slope("hades_core:tuff_baked", { + description = S("Burned Tuff"), + }, + 80 +) + +naturalslopeslib.register_slope("hades_core:mossytuff", { + description = S("Mossy Tuff"), + }, + 80 +) + +naturalslopeslib.register_slope("hades_core:marble", { + description = S("Marble"), + }, + 80 +) + +naturalslopeslib.register_slope("hades_core:essexite", { + description = S("Essexite"), + }, + 100 +) + +naturalslopeslib.register_slope("hades_core:stone_baked", { + description = S("Burned Stone"), + }, + 100 +) + +naturalslopeslib.register_slope("hades_core:ash", { + description = S("Volcanic Ash"), + }, + 3 +) + +naturalslopeslib.register_slope("hades_core:fertile_sand", { + description = S("Fertile Sand"), + }, + 15 +) + +naturalslopeslib.register_slope("hades_core:gravel", { + description = S("Gravel"), + }, + 20 +) + +naturalslopeslib.register_slope("hades_core:gravel_volcanic", { + description = S("Volcanic Gravel"), + }, + 20 +) + +naturalslopeslib.register_slope("hades_core:sandstone", { + description = S("Sandtone"), + drop = "hades_core:sandstone", + }, + 50 +) + +naturalslopeslib.register_slope("hades_core:clay", { + description = S("Clay"), + }, + 35 +) + +naturalslopeslib.register_slope("hades_core:cobble", { + description = S("Cobblestone"), + }, + 60 +) + +naturalslopeslib.register_slope("hades_core:cobble_baked", { + description = S("Burned Cobblestone"), + }, + 60 +) + +naturalslopeslib.register_slope("hades_core:mossycobble", { + description = S("Mossy Cobblestone"), + }, + 60 +) diff --git a/textures/ns_hades_palette_grass.png b/textures/ns_hades_palette_grass.png new file mode 100644 index 0000000..6c5af7d Binary files /dev/null and b/textures/ns_hades_palette_grass.png differ diff --git a/tools.lua b/tools.lua new file mode 100644 index 0000000..cfe31f7 --- /dev/null +++ b/tools.lua @@ -0,0 +1,43 @@ +local function use_shape(itemstack, user, pointed_thing) + local tool_def = itemstack:get_definition() + local node_pos = minetest.get_pointed_thing_position(pointed_thing, false) + local node = minetest.get_node(node_pos) + local node_def = minetest.registered_nodes[node.name] + local dig_params = minetest.get_dig_params(node_def.groups, tool_def.tool_capabilities) + if not dig_params.diggable then + return itemstack + end + local chance = 1.0 / (dig_params.time * 2.0) + local success = (chance >= 1.0 or math.random() < chance) + if success then + local changed = naturalslopeslib.update_shape(node_pos, node) + if node_def.sounds.dug then + minetest.sound_play(node_def.sounds.dug, {pos = node_pos}, true) + end + if changed then + itemstack:add_wear(math.ceil(dig_params.wear / 4.0)) + end + else + if node_def.sounds.dig then + minetest.sound_play(node_def.sounds.dig, {to_player = user:get_player_name()}, true) + elseif node_def.sounds.dug then + minetest.sound_play(node_def.sounds.dug, {to_player = user:get_player_name()}, true) + end + end + return itemstack +end + +local shaper_tools = {"hades_core:pick_wood", "hades_core:pick_stone", "hades_core:pick_steel", +"hades_core:pick_bronze", "hades_core:pick_mese", "hades_core:pick_prism", +"hades_core:shovel_wood", "hades_core:shovel_stone", "hades_core:shovel_steel", "hades_core:shovel_bronze", +"hades_core:shovel_mese", "hades_core:shovel_prism", +"hades_core:axe_wood", "hades_core:axe_stone", "hades_core:axe_steel", "hades_core:axe_bronze", +"hades_core:axe_mese", "hades_core:axe_prism", +"hades_core:sword_wood", "hades_core:sword_stone", "hades_core:sword_steel", "hades_core:sword_bronze", +"hades_core:sword_mese", "hades_core:sword_prism"} + +for _, tool in ipairs(shaper_tools) do + minetest.override_item(tool, { + on_place = use_shape + }) +end