diff --git a/mods/rp_default/README.txt b/mods/rp_default/README.txt index 29b4f071..60ba0eb5 100644 --- a/mods/rp_default/README.txt +++ b/mods/rp_default/README.txt @@ -10,6 +10,8 @@ See `API.md` ## Licensing +Note: The “*” character in file names below is a placeholder that means “any text”. + Sound licenses: * default_shears_cut.ogg: * Source: https://freesound.org/people/SmartWentCody/sounds/179015/ @@ -17,6 +19,10 @@ Sound licenses: * default_tool_breaks.ogg: * Source: https://freesound.org/people/JustInvoke/sounds/446118/ * Author: JustInvoke (CC BY 3.0) + * `rp_default_airweed_bubbles.*.ogg`: + * Source: https://freesound.org/people/spookymodem/sounds/202094/ + * Author: spookymodem (CC0) + * Sounds modified by Wuzzy * All other sounds: CC0 Texture license: CC BY-SA 4.0 * rp_default_reed*, rp_default_fertilize_particle*, rp_default_torch_smoke_anim.png: diff --git a/mods/rp_default/functions.lua b/mods/rp_default/functions.lua index f2a454cc..7e4a1b1d 100644 --- a/mods/rp_default/functions.lua +++ b/mods/rp_default/functions.lua @@ -5,6 +5,8 @@ local S = minetest.get_translator("rp_default") local SAPLING_RECHECK_TIME_MIN = 60 local SAPLING_RECHECK_TIME_MAX = 70 +local AIRWEED_RECHARGE_TIME = 5.0 -- how many seconds it takes for an airweed to become usable again + local GRAVITY = tonumber(minetest.settings:get("movement_gravity") or 9.81) -- Maximum growth height of cactus on dry dirt, normally @@ -423,6 +425,19 @@ function default.grow_underwater_leveled_plant(pos, node, add) return true, top end +-- Starts the timer of an inert airweed at pos +-- (if not started already) so it will become +-- usable to get air bubbles soon. +-- Do not call this function on any other node type! +function default.start_inert_airweed_timer(pos) + local timer = minetest.get_node_timer(pos) + if timer:is_started() then + return + else + timer:start(AIRWEED_RECHARGE_TIME) + end +end + -- Make preexisting sapling restart the growing process minetest.register_lbm( @@ -438,6 +453,18 @@ minetest.register_lbm( } ) +-- Make sure to restart the timer of inert airweeds +minetest.register_lbm( + { + label = "Restart inert airweed timers", + name = "rp_default:restart_inert_airweed_timers", + nodenames = {"group:airweed_inert"}, + action = function(pos, node) + default.start_inert_airweed_timer(pos) + end + } +) + -- Update sign formspecs/infotexts minetest.register_lbm( { @@ -740,10 +767,10 @@ minetest.register_abm( -- dirt with grass becomes dirt if covered end }) -minetest.register_abm( -- seagrass dies if not underwater +minetest.register_abm( -- seagrass and airweed dies if not underwater { - label = "Sea grass decay", - nodenames = {"group:seagrass"}, + label = "Sea grass / airweed decay", + nodenames = {"group:seagrass", "group:airweed"}, interval = 10, chance = 20, action = function(pos, node) diff --git a/mods/rp_default/nodes_waterlife.lua b/mods/rp_default/nodes_waterlife.lua index b294b7b4..2f2425ce 100644 --- a/mods/rp_default/nodes_waterlife.lua +++ b/mods/rp_default/nodes_waterlife.lua @@ -1,6 +1,8 @@ local S = minetest.get_translator("rp_default") -local ALGA_BLOCK_SLIPPERY = 2 +local ALGA_BLOCK_SLIPPERY = 2 -- Slippery level of alga block + +local AIRWEED_ADD_BREATH = 1 -- How much breath points an airweed restores by a single use local function get_sea_plant_on_place(base, paramtype2) return function(itemstack, placer, pointed_thing) @@ -213,6 +215,195 @@ register_seagrass_on("fertilized_swamp_dirt", "rp_default:fertilized_swamp_dirt" register_seagrass_on("fertilized_sand", "rp_default:fertilized_sand", waterplant_base_tiles("default_sand.png", "seagrass", true), true) +local register_airweed = function(plant_id, selection_box, drop, append, basenode, basenode_tiles, on_rightclick, on_timer, on_construct, fertilize_info, is_inert) + local groups = {snappy = 2, dig_immediate = 3, airweed = 1, plant = 1, rooted_plant = 1} + if is_inert then + groups.airweed_inert = 1 + end + + local _fertilized_node + local def_base = minetest.registered_nodes[basenode] + if minetest.get_item_group(basenode, "fall_damage_add_percent") ~= 0 then + groups.fall_damage_add_percent = def_base.groups.fall_damage_add_percent + end + if fertilize_info == true then + groups.plantable_fertilizer = 1 + elseif type(fertilize_info) == "string" then + _fertilized_node = "rp_default:"..plant_id.."_on_"..fertilize_info + end + minetest.register_node( + "rp_default:"..plant_id.."_on_"..append, + { + drawtype = "plantlike_rooted", + paramtype = "light", + selection_box = selection_box, + collision_box = { + type = "regular", + }, + visual_scale = 1.14, + tiles = basenode_tiles, + special_tiles = {"rp_default_"..plant_id.."_clump.png"}, + inventory_image = "rp_default_plantlike_rooted_inv_"..append..".png^rp_default_plantlike_rooted_inv_"..plant_id..".png", + wield_image = "rp_default_plantlike_rooted_inv_"..append..".png^rp_default_plantlike_rooted_inv_"..plant_id..".png", + waving = 1, + walkable = true, + groups = groups, + sounds = rp_sounds.node_sound_leaves_defaults(), + node_dig_prediction = basenode, + on_rightclick = on_rightclick, + on_timer = on_timer, + on_construct = on_construct, + after_destruct = function(pos) + local newnode = minetest.get_node(pos) + if minetest.get_item_group(newnode.name, "airweed") == 0 then + minetest.set_node(pos, {name=basenode}) + minetest.check_for_falling(pos) + end + end, + _fertilized_node = _fertilized_node, + _waterplant_base_node = basenode, + drop = drop, + }) +end +local register_airweed_on = function(append, basenode, basenode_tiles, fertilize_info) + + local on_timer = function(pos) + local node = minetest.get_node(vector.add(pos, vector.new(0,1,0))) + if minetest.get_item_group(node.name, "water") == 0 then + -- Restart timer if airweed is not in water + default.start_inert_airweed_timer(pos) + return + end + + -- Airweed is ready again + minetest.set_node(pos, {name="rp_default:airweed_on_"..append}) + end + + local on_construct = function(pos) + default.start_inert_airweed_timer(pos) + end + + -- on_rightclick for "inert" airweed: Start timer + -- in case the airweed timer was not started before + -- for some reason. This acts as a simple fallback, + -- just in case. + local on_rightclick_inert = function(pos) + default.start_inert_airweed_timer(pos) + end + + -- on_rightclick for "charged" airweed: Increase breath of clicker + -- and players nearby. Also make airweed inert + local on_rightclick_charged = function(pos, node, clicker, itemstack, pointed_thing) + -- First check if the *plant* was rightclicked (the base node does not count) + local face_pos + if pointed_thing and clicker and clicker:is_player() then + face_pos = minetest.pointed_thing_to_face_pos(clicker, pointed_thing) + if face_pos and (face_pos.y < pos.y + 0.5) then + -- The base node was rightclicked: Do nothing + return + end + end + + local bubble_pos = {x=pos.x,y=pos.y+1,z=pos.z} + + -- No bubbles if the plant is not in water + local bnode = minetest.get_node(bubble_pos) + if minetest.get_item_group(bnode.name, "water") == 0 then + return + end + + -- Effect particles + sound + minetest.add_particlespawner({ + amount = 20, + time = 0.1, + pos = { + min = { + x = bubble_pos.x - 0.4, + y = bubble_pos.y, + z = bubble_pos.z - 0.4 + }, + max = { + x = bubble_pos.x + 0.4, + y = bubble_pos.y + 0.2, + z = bubble_pos.z + 0.4 + }, + }, + vel = { + min = {x = -1.5, y = 0, z = -1.5}, + max = {x = 1.5, y = 0, z = 1.5}, + }, + acc = { + min = {x = -0.5, y = 4, z = -0.5}, + max = {x = 0.5, y = 1, z = 0.5}, + }, + drag = { x = 0.7, y = 0, z = 0.7 }, + exptime = {min=0.3,max=0.8}, + size = {min=0.7, max=2.4}, + texture = { + name = "bubble.png", + alpha_tween = { 1, 0, start = 0.75 } + }, + }) + minetest.sound_play({name = "rp_default_airweed_bubbles", gain = 0.6}, {pos = bubble_pos}, true) + + -- Set airweed inert (in which it can't release bubbles + -- temporarily) + minetest.set_node(pos, {name="rp_default:airweed_inert_on_"..append}) + + -- Always increase breath of clicker + if clicker and clicker:is_player() then + clicker:set_breath(clicker:get_breath() + AIRWEED_ADD_BREATH) + end + + -- Also increase breath of other players nearby + -- TODO: Also mobs + local min = vector.add(bubble_pos, vector.new(-1.5,-1,-1.5)) + local max = vector.add(bubble_pos, vector.new(1.5,1.5,1.5)) + local objs = minetest.get_objects_in_area(min, max) + for o=1, #objs do + local obj = objs[o] + if obj:is_player() and obj ~= clicker then + obj:set_breath(obj:get_breath() + AIRWEED_ADD_BREATH) + end + end + end + + -- Inert airweed (bubbles not ready) + register_airweed("airweed_inert", + { type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + {-0.5, 0.5, -0.5, 0.5, 17/16, 0.5}, + }}, "rp_default:airweed", append, basenode, basenode_tiles, on_rightclick_inert, on_timer, on_construct, fertilize_info, true) + + -- "charged" airweed (bubbles ready) + register_airweed("airweed", + { type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + {-0.5, 0.5, -0.5, 0.5, 22/16, 0.5}, + }}, "rp_default:airweed", append, basenode, basenode_tiles, on_rightclick_charged, nil, nil, fertilize_info) +end + +minetest.register_craftitem("rp_default:airweed", { + description = S("Airweed"), + _tt_help = S("Gives back breath") .. "\n".. + S("Grows underwater on dirt, swamp dirt or sand"), + inventory_image = "rp_default_airweed_clump_inventory.png", + wield_image = "rp_default_airweed_clump_inventory.png", + on_place = get_sea_plant_on_place("airweed_inert", "wallmounted"), + groups = { node = 1, airweed = 1, plant = 1 }, +}) + +register_airweed_on("dirt", "rp_default:dirt", waterplant_base_tiles("default_dirt.png", "airweed", false), "fertilized_dirt") +register_airweed_on("swamp_dirt", "rp_default:swamp_dirt", waterplant_base_tiles("default_swamp_dirt.png", "airweed", false), "fertilized_swamp_dirt") +register_airweed_on("sand", "rp_default:sand", waterplant_base_tiles("default_sand.png", "airweed", false), "fertilized_sand") +register_airweed_on("fertilized_dirt", "rp_default:fertilized_dirt", waterplant_base_tiles("default_dirt.png", "airweed", true), true) +register_airweed_on("fertilized_swamp_dirt", "rp_default:fertilized_swamp_dirt", waterplant_base_tiles("default_swamp_dirt.png", "airweed", true), true) +register_airweed_on("fertilized_sand", "rp_default:fertilized_sand", waterplant_base_tiles("default_sand.png", "airweed", true), true) + + + -- Alga local register_alga_on = function(append, basenode, basenode_tiles, max_height, fertilize_info) if not max_height then diff --git a/mods/rp_default/sounds/rp_default_airweed_bubbles.1.ogg b/mods/rp_default/sounds/rp_default_airweed_bubbles.1.ogg new file mode 100644 index 00000000..f6442266 Binary files /dev/null and b/mods/rp_default/sounds/rp_default_airweed_bubbles.1.ogg differ diff --git a/mods/rp_default/sounds/rp_default_airweed_bubbles.2.ogg b/mods/rp_default/sounds/rp_default_airweed_bubbles.2.ogg new file mode 100644 index 00000000..2f1fbd5f Binary files /dev/null and b/mods/rp_default/sounds/rp_default_airweed_bubbles.2.ogg differ diff --git a/mods/rp_default/textures/rp_default_airweed_clump.png b/mods/rp_default/textures/rp_default_airweed_clump.png new file mode 100644 index 00000000..29f32449 Binary files /dev/null and b/mods/rp_default/textures/rp_default_airweed_clump.png differ diff --git a/mods/rp_default/textures/rp_default_airweed_clump_inventory.png b/mods/rp_default/textures/rp_default_airweed_clump_inventory.png new file mode 100644 index 00000000..36d9e5ee Binary files /dev/null and b/mods/rp_default/textures/rp_default_airweed_clump_inventory.png differ diff --git a/mods/rp_default/textures/rp_default_airweed_inert_clump.png b/mods/rp_default/textures/rp_default_airweed_inert_clump.png new file mode 100644 index 00000000..05661ec3 Binary files /dev/null and b/mods/rp_default/textures/rp_default_airweed_inert_clump.png differ diff --git a/mods/rp_default/textures/rp_default_plantlike_rooted_airweed_roots.png b/mods/rp_default/textures/rp_default_plantlike_rooted_airweed_roots.png new file mode 100644 index 00000000..26027a05 Binary files /dev/null and b/mods/rp_default/textures/rp_default_plantlike_rooted_airweed_roots.png differ diff --git a/mods/rp_default/textures/rp_default_plantlike_rooted_inv_airweed.png b/mods/rp_default/textures/rp_default_plantlike_rooted_inv_airweed.png new file mode 100644 index 00000000..07387245 Binary files /dev/null and b/mods/rp_default/textures/rp_default_plantlike_rooted_inv_airweed.png differ diff --git a/mods/rp_default/textures/rp_default_plantlike_rooted_inv_airweed_inert.png b/mods/rp_default/textures/rp_default_plantlike_rooted_inv_airweed_inert.png new file mode 100644 index 00000000..8fd0556c Binary files /dev/null and b/mods/rp_default/textures/rp_default_plantlike_rooted_inv_airweed_inert.png differ