From 0a19253ae320628e90419e39a1d3e7e41fda2cf2 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 9 Jun 2022 01:59:28 +0200 Subject: [PATCH] Add vine --- DEV_GROUPS.md | 1 + mods/rp_attached/init.lua | 8 ++ mods/rp_attached/mod.conf | 3 + mods/rp_default/mapgen_deco.lua | 75 +++++++++++++++++- mods/rp_default/nodes_plants.lua | 70 ++++++++++++++++ mods/rp_default/textures/rp_default_vine.png | Bin 0 -> 5397 bytes .../textures/rp_default_vine_inventory.png | Bin 0 -> 5656 bytes mods/rp_supertools/init.lua | 6 ++ mods/rp_util/init.lua | 38 +++++++-- 9 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 mods/rp_attached/init.lua create mode 100644 mods/rp_attached/mod.conf create mode 100644 mods/rp_default/textures/rp_default_vine.png create mode 100644 mods/rp_default/textures/rp_default_vine_inventory.png diff --git a/DEV_GROUPS.md b/DEV_GROUPS.md index 85b1e24..af0153d 100644 --- a/DEV_GROUPS.md +++ b/DEV_GROUPS.md @@ -81,6 +81,7 @@ This is the list of all groups used for nodes. Note: If no number/rating is spec * `interactive_node`: Node can be interacted with (excluding pure container nodes) * `no_spawn_allowed_on`: If set, players can not (initially) spawn on this block * `spawn_allowed_in`: If set, players can spawn into this block (note: this group is ignored for the 'air' and 'ignore' nodes) +* `_attached_node_top=1`: Node attaches to the top of another node. If the node above disappears, the node itself detaches ### Node categorization diff --git a/mods/rp_attached/init.lua b/mods/rp_attached/init.lua new file mode 100644 index 0000000..f8f4576 --- /dev/null +++ b/mods/rp_attached/init.lua @@ -0,0 +1,8 @@ +minetest.register_on_dignode(function(pos, oldnode, digger) + local below = vector.add(pos, vector.new(0,-1,0)) + local belownode = minetest.get_node(below) + local at = minetest.get_item_group(belownode.name, "_attached_node_top") == 1 + if at then + util.dig_down(pos, belownode, digger) + end +end) diff --git a/mods/rp_attached/mod.conf b/mods/rp_attached/mod.conf new file mode 100644 index 0000000..bb8ab3c --- /dev/null +++ b/mods/rp_attached/mod.conf @@ -0,0 +1,3 @@ +name = rp_attached +description = Adds more ways for nodes to be attached +depends = rp_util diff --git a/mods/rp_default/mapgen_deco.lua b/mods/rp_default/mapgen_deco.lua index 6002a42..7d522a3 100644 --- a/mods/rp_default/mapgen_deco.lua +++ b/mods/rp_default/mapgen_deco.lua @@ -1573,6 +1573,80 @@ default.register_decoration( seed = 43905, }, }) + +-- Vine decorations +-- +default.register_decoration( + { + deco_type = "simple", + place_on = {"rp_default:stone", "group:dirt"}, + sidelen = 16, + fill_ratio = 0.02, + biomes = { "Birch Forest", "Birch Forest Underwater", "Dense Oak Forest", "Forest", "Forest Underwater", "Grassland", "Grassland Underwater", "Grove", "Grove Underwater", "Oak Forest", "Oak Forest Underwater", "Tall Birch Forest", "Tall Birch Forest Underwater", "Tall Oak Forest", "Tall Oak Forest Underwater", }, + decoration = {"rp_default:vine"}, + y_min = -30, + y_max = default.GLOBAL_Y_MAX, + height = 1, + height_max = 5, + flags = "all_ceilings", +}) +default.register_decoration( + { + deco_type = "simple", + place_on = {"rp_default:stone", "group:dirt"}, + sidelen = 16, + fill_ratio = 0.03, + biomes = { "Dense Grassland", "Shrubbery", "Shrubbery Underwater", "Oak Shrubbery", "Oak Shrubbery Underwater" }, + decoration = {"rp_default:vine"}, + y_min = -30, + y_max = default.GLOBAL_Y_MAX, + height = 1, + height_max = 10, + flags = "all_ceilings", +}) +default.register_decoration( + { + deco_type = "simple", + place_on = {"rp_default:stone", "group:dirt"}, + sidelen = 16, + fill_ratio = 0.04, + biomes = { "Dense Grassland", "Dense Oak Forest", "Grove", "Grove Underwater" }, + decoration = {"rp_default:vine"}, + y_min = -30, + y_max = default.GLOBAL_Y_MAX, + height = 1, + height_max = 7, + flags = "all_ceilings", +}) +default.register_decoration( + { + deco_type = "simple", + place_on = {"rp_default:stone", "group:dirt"}, + sidelen = 16, + fill_ratio = 0.2, + biomes = { "Wilderness", "Wilderness Underwater", }, + decoration = {"rp_default:vine"}, + y_min = -30, + y_max = default.GLOBAL_Y_MAX, + height = 1, + height_max = 7, + flags = "all_ceilings", +}) +default.register_decoration( + { + deco_type = "simple", + place_on = {"rp_default:stone", "group:dirt"}, + sidelen = 16, + fill_ratio = 0.08, + biomes = { "Marsh", "Marsh Beach", "Marsh Underwater", "Deep Forest", "Dense Oak Forest", "Mystery Forest", "Mystery Forest Underwater" }, + decoration = {"rp_default:vine"}, + y_min = -30, + y_max = default.GLOBAL_Y_MAX, + height = 1, + height_max = 20, + flags = "all_ceilings", +}) + end -- Papyrus decorations @@ -2156,4 +2230,3 @@ default.register_decoration( y_max = 1, }) - diff --git a/mods/rp_default/nodes_plants.lua b/mods/rp_default/nodes_plants.lua index 4bc376e..8b39438 100644 --- a/mods/rp_default/nodes_plants.lua +++ b/mods/rp_default/nodes_plants.lua @@ -72,6 +72,76 @@ minetest.register_node( end, }) +-- Vine + +minetest.register_node( + "rp_default:vine", + { + description = S("Vine"), + _tt_help = S("Hangs from stone or dirt"), + drawtype = "plantlike", + tiles = {"rp_default_vine.png"}, + use_texture_alpha = "clip", + inventory_image = "rp_default_vine_inventory.png", + wield_image = "rp_default_vine_inventory.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + climbable = true, + selection_box = { + type = "fixed", + fixed = {-2/16, -0.5, -2/16, 2/16, 0.5, 2/16 }, + }, + floodable = true, + groups = {_attached_node_top = 1, snappy = 3, plant = 1, vine = 1}, + sounds = rp_sounds.node_sound_leaves_defaults(), + after_dig_node = function(pos, node, metadata, digger) + util.dig_down(pos, node, digger) + end, + after_destruct = function(pos, oldnode) + util.dig_down(pos, oldnode) + end, + on_flood = function(pos, oldnode, newnode) + util.dig_down(pos, oldnode) + end, + on_place = function(itemstack, placer, pointed_thing) + -- Boilerplate to handle pointed node handlers + local handled, handled_itemstack = util.on_place_pointed_node_handler(itemstack, placer, pointed_thing) + if handled then + return handled_itemstack + end + + -- Find position to place vine at + local place_in, place_floor = util.pointed_thing_to_place_pos(pointed_thing, true) + if place_in == nil then + return itemstack + end + local ceilingnode = minetest.get_node(place_floor) + + -- Ceiling must be stone, dirt or another vine + if minetest.get_item_group(ceilingnode.name, "dirt") == 0 and ceilingnode.name ~= "rp_default:stone" and ceilingnode.name ~= "rp_default:vine" then + return itemstack + end + + -- Check protection + if minetest.is_protected(place_in, placer:get_player_name()) and + not minetest.check_player_privs(placer, "protection_bypass") then + minetest.record_protection_violation(pos, placer:get_player_name()) + return itemstack + end + + -- Place vine + minetest.set_node(place_in, {name = itemstack:get_name()}) + + -- Reduce item count + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + + return itemstack + end, +}) + -- Fern minetest.register_node( diff --git a/mods/rp_default/textures/rp_default_vine.png b/mods/rp_default/textures/rp_default_vine.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4e87ff6f8c07c735bf4385aea6a10d79aa50e7 GIT binary patch literal 5397 zcmeHKX;>5I7LFjR;8lUks>I-R0Vm63Ad5t{unUAm6t9Sr$pi+-LK4C%Wl@WeQo+g< z6)n~UsT*jq78f?FB8q~drAk|6RYY;QDx%y;K!xY_kI&Qo^UE{I%=ex1o^#&soimwD zyg+YbLn}i9fnebxnlF4U!mb?dS+te!LvHeU@?b`JX6?>DMad45;CK63P7 z%OCG*&vQFBlo!kV=B&6lSDv*tBMN=d)$pK2?~9q@=Yzx9WwTUOwm|7KO6pTaak*>W zW1|R8l+8(sjQQx-(lYtnl3WY-CC1%to1bL39muLW*&XV%?%am&9#=*x`EQiRO(Lt0 zdJXQ*sZRsk7d1!vIHwkxWH#?8HPy#nY}~X46clAHy@-AenABzHSs8S-0xhP1~5QAg#~Jv^==XZQWN}?TNaB1!h`u zG{VoMyV-0Ypyyi5vFuCpb&DSE;pj(IUR&k#=0SVx#;w+{ed|#^oN?yV3Kt7xzgFwr zBWJb9J^cd_I<6Le+Me?g`qY#hZBVJ?TfxkEv_SO*k+O zTVh=6xst7AWMDyvn^!n11q~-LTU~im6vefA7T;Q&nlewXaH@E-?@FuP3lAT(v5eK@ z%T*>AoVOZP>o}*y<;Vb?ZZ>FYVIzR(P|YAG5RFM@o+^uiRg8Gxo^7 zge@C~uZOe=fs?HV?Y>Fvt2}VzZt5UPys`1enO-(n-?2jPQ&q~=;j%NeR;7oA__2XE z9OAB3tXXz#@qz@IZvAZ?t^4dnuCC9znyoj~ZaHQn{xoISszP1;~RYA+Xuyd=qOQ_>n&?YO{;R6Sa}Gw?Z>XfKaM<*f>+9zBdl{}zt50|iq!Xcq+&nQi+;re| z=H@pqu5(IV?QT^6(`NNnS@FSwgSm>s*5NH@Z8KQbE;eV=lScN;#k_xUPI+ihR{Y;B zx`b8oJ3-&R*7Il$2xRQ-2zF=ek9CU^U5@B*7gvw;-y1RB-Xtk#G3qZ{;>9kwvc0LN zCHIGdbP_+d|2GeXXZvX};fL1a~!8n&CzF)`}U68X>Y)!3Pjx-IGgH>GkN+RkC*+S?;8C2p}x6f&K;Nb-F;=XxYo5$*4lFJI`sf#-1I!CG0rIfVIy zthUj)m7Qaozg*8eI&$`E9k(aijn^;vUib7Hi3*9CdA}~frSopuoio}aSL{Qt>`HLG zx!7)tpW&&IiW#Y%lzM$q-ulL6>jF*Np4ddad@}TcTzC9*%UjkSzdAu?5OEj!6FgHg zBS^A}-Mj9dg@eE05Nl|goB6zquAc^;TK5(;WbCq}SCypPv#8`f;GfEm_=UIWK<@p# zir}*@y;b!o`NvlsKK@_M>uGj6BDCZo^krc^shH@Vsbbrg*Slwje`RW7*%6fb>Pwq* zKID?sW>neYZ*|Rz?(2=_{C0Qy`AY_jMMYDyDb;UjTI-cr;SJU2z82LaYE9jh<#71^ zQOB&3pjPYIK*rSP5^eKavjaM{$w`@Y3nIaJ-iFtno9EZQv0N8A$Kpqw;r2V79dDTH z2vs+h59>0SQ@#AZIWsskC{2=#?!sQa)TV^VR6mu5-NqjnZ!!GAurgp785hT;Zw2LB zfW-)^hQh(g7>)z+Q7Q|hgMa{`Isy;~F#tX!Z~}yM2FQd2RL~KjO@IiJVYn*c_=#Dm zp#(S-3l%tlbQT?;ISK>-By{2fFb)Brun=;D1^946G*AMB?In?kV0=3<5gd(Dq~d7J zf|_u)8_$|`9i|~Llf?uWR1^dt0h11}9GOf2#2M#1LUa%UohGBpB|=3KEJNL*@k;S(Z~G~uFKFRpAx<1qONeq0F@n?1YWpo*Se5XUj z_#eF_{EcmfD%=f!+tcOydvgi9)SsjvgOm7-fz&5LP9RJ(Q6EzX+jm;vlX?o@08hOh zU46ajz&3K74C-1@!hAf5}s*E5iN#C>h{ F{{T$+3;+NC literal 0 HcmV?d00001 diff --git a/mods/rp_default/textures/rp_default_vine_inventory.png b/mods/rp_default/textures/rp_default_vine_inventory.png new file mode 100644 index 0000000000000000000000000000000000000000..45adc84d3d38113042c4e13352c83f130e426fcf GIT binary patch literal 5656 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 literal 0 HcmV?d00001 diff --git a/mods/rp_supertools/init.lua b/mods/rp_supertools/init.lua index c071a82..8e4d961 100644 --- a/mods/rp_supertools/init.lua +++ b/mods/rp_supertools/init.lua @@ -90,6 +90,12 @@ minetest.register_craftitem( minetest.set_node(top, {name=unode.name}) used = true end + elseif (unode.name == "rp_default:vine") then + local top = vector.add(upos, vector.new(0,-1,0)) + if minetest.get_node(top).name == "air" then + minetest.set_node(top, {name=unode.name}) + used = true + end end if used then diff --git a/mods/rp_util/init.lua b/mods/rp_util/init.lua index 72e2b24..475d539 100644 --- a/mods/rp_util/init.lua +++ b/mods/rp_util/init.lua @@ -211,13 +211,20 @@ end -- `digger` is a player object that will be treated as -- the 'digger' of said nodes. function util.dig_up(pos, node, digger) + if node.name == "ignore" then + return + end local np = {x = pos.x, y = pos.y + 1, z = pos.z} local nn = minetest.get_node(np) if nn.name == node.name then if digger then - minetest.node_dig(np, nn, digger) + minetest.node_dig(np, nn, digger) else - minetest.remove_node(np) + while nn.name == node.name do + minetest.remove_node(np) + np.y = np.y + 1 + nn = minetest.get_node(np) + end end end end @@ -227,10 +234,21 @@ end -- `digger` is a player object that will be treated as -- the 'digger' of said nodes. function util.dig_down(pos, node, digger) + if node.name == "ignore" then + return + end local np = {x = pos.x, y = pos.y - 1, z = pos.z} local nn = minetest.get_node(np) if nn.name == node.name then - minetest.node_dig(np, nn, digger) + if digger then + minetest.node_dig(np, nn, digger) + else + while nn.name == node.name do + minetest.remove_node(np) + np.y = np.y - 1 + nn = minetest.get_node(np) + end + end end end @@ -241,13 +259,21 @@ end -- into account. -- -- Takes a pointed_thing from a on_place callback or similar. +-- * `pointed_thing`: A pointed thing +-- * `top`: (optional): If true, is for plant placement at ceiling +-- instead (default: false) +-- -- Returns `, ` if successful, `nil` otherwise -- * `place_in`: Where the node is suggested to be placed -- * `place_on`: Directly below place_in -function util.pointed_thing_to_place_pos(pointed_thing) +function util.pointed_thing_to_place_pos(pointed_thing, top) if pointed_thing.type ~= "node" then return nil end + local offset = -1 + if top then + offset = 1 + end local place_in, place_on local undernode = minetest.get_node(pointed_thing.under) local underdef = minetest.registered_nodes[undernode.name] @@ -256,10 +282,10 @@ function util.pointed_thing_to_place_pos(pointed_thing) end if underdef.buildable_to then place_in = pointed_thing.under - place_on = vector.add(place_in, vector.new(0, -1, 0)) + place_on = vector.add(place_in, vector.new(0, offset, 0)) else place_in = pointed_thing.above - place_on = vector.add(place_in, vector.new(0, -1, 0)) + place_on = vector.add(place_in, vector.new(0, offset, 0)) local inname = minetest.get_node(place_in).name local indef = minetest.registered_nodes[inname] if not indef or not indef.buildable_to then