commit fce9f492c7f75bd56d9395bc92bb153c610799a4 Author: Vanessa Ezekowitz Date: Thu Nov 29 22:59:45 2012 -0500 initial commit diff --git a/README b/README new file mode 100644 index 0000000..5f0612b --- /dev/null +++ b/README @@ -0,0 +1,84 @@ +README file for Plantlife mod, by Vanessa Ezekowitz +--------------------------------------------------- + +Plantlife is a combined form of my Flowers, Jungle Grass, and Poison Ivy mods +and has been significantly rewritten and re-organized. This mod supplies all +three of these components and should be 100% compatible with mods that used the +old versions. + +Its purpose is to add various kinds of flowers, cotton plants, water foliage, +poison ivy, and jungle grass in a few sizes. All of these are spawned as +normal nodes and can be collected and used in any recipes that depend on the +old mods. + +Spawning of plandts is sensitive to the amount of available light. Flowers, +cotton, and waterlilies only spawn when there at least a signficant amount of +light. Seaweed will grow only in dimly-lit areas. Jungle grass and poison ivy +also grow in the daytime, but require less light than flowers. + +------------------------------------------------------------------------------ + +Important details: + +Configuration: Any of the three components of this mod can be disabled by +editing plants/init.lua, near the beginning of the file, and changing one or +more of these lines to false: + +local enable_flowers = true +local enable_junglegrass = true +local enable_poisonivy = true + +Dependencies: Just the game's default stuff. + +Recommends: Nothing in particular. + +Conflicts: This mod should not be installed alongside the original Flowers, +Jungle Grass, or Poison Ivy mods. If those exist, delete them, as this mod +supplies all of their functionality. + +Software Requirements: This mod was written for Minetest 0.4.4 or later, but it +should work on pretty much any old or recent 0.4.x version. It will not work +with 0.3.x since that version does not support modding. + +------------------------------------------------------------------------------ + +Crafting: + +Only Flowers have crafting recipes. For a flower pot, put three +clay bricks in the crafting grid in a "v" shape like so (yields 1): + + - - - + B - B + - B - + +To put a flower into a pot, just put one of each into the crafting grid. + +------------------------------------------------------------------------------ + +Notes: + +Flowers has been completely rewritten, almost from scratch, using the most +recent and advanced features the game engine has to offer. It should be +significantly faster than the original Ironzorg Flowers mod. Flowers and +cotton spawn on grass only, seaweed spawns on water or grass close to the +shoreline, or on very small stone islands in water. Waterlilies of course +spawn on water. + +There are four different sizes of jungle grasses, all of which yield a single +junglegrass object when gathered (so all four sizes may be used where jungle +grass is called for). The largest size uses the game's standard jungle grass +node, while the others are defined by this mod. + +Junglegrass will spawn on grass, sand, desert sand and the tops of papyrus and +cactus (though rarely), and will do so anywhere in the map. Grass on the +ground will grow and eventually disappear (die), while grass in the desert will +grow and eventually turn into dry shrubs. + +Poison Ivy will spawn on grass and in some cases, on vertical surfaces +including trees and jungle trees where they meet the dirt or grass. Ivy +previously spawned on the ground taller/thicker or start climbing up said +vertical surfaces and trees. + +At present, the poison ivy presents little more than an annoyance - they can +only be cut down and either re-planted or thrown away. No damage is done by +harvesting them, yet. ;-) diff --git a/README~ b/README~ new file mode 100644 index 0000000..6005768 --- /dev/null +++ b/README~ @@ -0,0 +1,60 @@ +--- README for Flowers: + +This is a mostly-rewrite of Ironzorg's flowers mod, using more recent features +in the game, to make the code perform better. + +Dependencies: none (just the game's default stuff) + +License: cc-by-sa 3.0 for the textures, WTFPL for everything else. + +--- README for Jungle Grass: + +Since recent versions of Minetest no longer contain jungle biomes, and +hence no jungle grass, I created this mod to re-add said grass back into +the game, with a twist: There are now four different sizes of grasses, +all of which yield a single junglegrass object when gathered (so all +four sizes may be used where jungle grass is called for). The largest +size uses the game's standard jungle grass node, while the others are +defined by this mod. + +Junglegrass will spawn on dirt, grass, sand, desert sand and the tops of +papyrus and cactus (though rarely), and will do so anywhere in the map. +Grass on the ground will grow and eventually die (or turn into dry +shrubs, in the desert), given enough time. + +Adjusting the overall spawn/growth rate is easily done by tweaking the +MAX_RATIO variable at the top of init.lua. A larger value results in +less frequent events. + +Dependencies: none (just the game's default stuff) + +License: cc-by-sa 3.0 for the textures, WTFPL for everything else. + +--- README for Poison Ivy: + +This is a mod for minetest and its forks to add poison ivy. + +Ivy will spawn on dirt or grass, and in some cases, on vertical +surfaces, trees, and jungle trees where they meet the dirt or grass. +Ivy previously spawned will occasionally grow taller/thicker or start +climbing up said vertical surfaces and trees. + +At present, the plants present little more than an annoyance - they can +only be cut down and either re-planted or thrown away. No damage is +done by harvesting them, yet. ;-) + +Mod based on ironzorg's flowers mod; I left the spawn rates the same so +the plants don't take over your world (in fact, they may take a few +day/night cycles before you start to notice them). If you want a really +overgrown environment just lower the MAX_RATIO and GROWING_DELAY +variables at the top of init.lua. + +Textures hand-drawn by me (16x16px). + +License: WTFPL (applies to all parts) + +Depends: None. + +No crafting recipes (didn't see a point :-) ). + + diff --git a/copyright.txt b/copyright.txt new file mode 100644 index 0000000..63d2431 --- /dev/null +++ b/copyright.txt @@ -0,0 +1,10 @@ +Ironzorg's Flowers mod served as the basis for the three mods that eventually +went into creating this file. Any code still remaining from that mod is +entirely his work (though I'm pretty sure it's all been phased out). + +Flowers textures by Ironzorg. + +Junglegrass textures are modified copies of the original one from the game's +default set. + +All remaining code, textures, etc. by Vanessa Ezekowitz. diff --git a/flowers-changelog.txt b/flowers-changelog.txt new file mode 100644 index 0000000..fbe7518 --- /dev/null +++ b/flowers-changelog.txt @@ -0,0 +1,24 @@ +Changelog +--------- + +2012-08-06: Tweaked selection boxes on all nodes. Tweaked seaweed to use +signlike instead of raillike drawtype, (still forced to only spawn flat as +usual). Adjusted light level limits to give it more time to grow. Created +this changelog file using github commit messages as the basis. Shrunk the +geranium flower down a bit to better match the others. + +2012-08-03: Tuned out the random-numbers-inside-ABM stuff. Uses the ABM's +chance setting instead. Should be approximately the same as before, but +hopefully using a tad less CPU. Minor tweak to ABM interval/growing delay. + +2012-08-01: Added blue geranium to the collection of flowers. + +2012-07-31: Disable debug by default. + +2012-07-30: many updates over the course of the day - first commit, removed +some redundant files, added wield/inventory image entries for each item, to +force the game to draw them properly (these shouldn't be needed, must be a +bug). Tweaked spawn code so that the radius check also includes the name of +the item being spawned as well as items in group:flower, that way all items can +have a radius test, and not just those in group:flower. Fiddled with the spawn +rates a bit. diff --git a/flowers/depends.txt b/flowers/depends.txt new file mode 100644 index 0000000..e69de29 diff --git a/flowers/init.lua b/flowers/init.lua new file mode 100644 index 0000000..e69de29 diff --git a/junglegrass-changelog.txt b/junglegrass-changelog.txt new file mode 100644 index 0000000..75f708b --- /dev/null +++ b/junglegrass-changelog.txt @@ -0,0 +1,24 @@ +Changelog +--------- + +2012-08-03: Mild rewrite to adapt the mod to use perlin noise while spawning. +Also got rid of the random-numbers-inside-abm stuff, now using the abm's own +'chance' parameter instead. Tuned various settings to try to retain the same +overall density and growth rates as in the previous version. Moved this +changelog into a separate file. + +2012-07-12: moved project to github. + +2012-07-09 (a bit later): tuned the spawn/grow rates a bit more, made the +numbers more sane. Added a radius check to limit the density of the spawned +grasses (they won't grow near each other or near dry shrubs or cactus, though +they still grow on the top of said cacti). + +2012-07-09: Added cactus, sand, and desert sand as spawning surfaces. Reduced +and tuned the spawn rates a bit to try to balance things out. Made that which +spawns on grass, dirt, or sand start out at any size, grow over time, and +eventually die off. Limited desert sand to only the first two sizes (the +smallest size will grow one step, eventually), which will eventually die and +turn into dry shrubs. Only the two smallest sizes can spawn on cactus or +papyrus (and they don't grow or die). Fixed slightly off-center smallest size. +Fixed selection boxes. diff --git a/junglegrass/depends.txt b/junglegrass/depends.txt new file mode 100644 index 0000000..e69de29 diff --git a/junglegrass/init.lua b/junglegrass/init.lua new file mode 100644 index 0000000..e69de29 diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..873e76a --- /dev/null +++ b/license.txt @@ -0,0 +1,3 @@ +For the original Ironzorg flower textures, WTFPL +For the rest of the textures, CC-BY-SA +For all code and everything else in this mod, WTFPL. diff --git a/modpack.txt b/modpack.txt new file mode 100644 index 0000000..e69de29 diff --git a/plants/depends.txt b/plants/depends.txt new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/plants/depends.txt @@ -0,0 +1 @@ +default diff --git a/plants/init.lua b/plants/init.lua new file mode 100644 index 0000000..6c5e1c3 --- /dev/null +++ b/plants/init.lua @@ -0,0 +1,448 @@ +-- Plantlife mod by Vanessa Ezekowitz +-- 2012-11-29 +-- +-- This mod combines all of the functionality from poison ivy, +-- flowers, and jungle grass. If you have any of these, you no +-- longer need them. +-- +-- License: +-- CC-BY-SA for most textures, except flowers +-- WTFPL for the flowers textures +-- WTFPL for all code and everything else + + +-- Edit these first few variables to turn the various parts on/off +-- or to tweak the overall settings. + +local enable_flowers = true +local enable_junglegrass = true +local enable_poisonivy = true + +local plantlife_debug = true + +local plantlife_seed_diff = 123 +local perlin_octaves = 3 +local perlin_persistence = 0.2 +local perlin_scale = 25 + +local plantlife_limit = 0.6 -- compared against perlin noise. lower = more abundant + +local spawn_delay = 2000 -- 2000 +local spawn_chance = 100 -- 100 +local grow_delay = 1000 -- 1000 +local grow_chance = 10 -- 10 + +-- Stuff from here on down shouldn't need to be edited. + +local loadstr = "[Plantlife] Loaded (enabled" + +local flowers_seed_diff = plantlife_seed_diff +local junglegrass_seed_diff = plantlife_seed_diff + 10 +local poisonivy_seed_diff = plantlife_seed_diff + 10 + +local flowers_list = { + { "Rose", "rose", spawn_delay, 10, spawn_chance , 10}, + { "Tulip", "tulip", spawn_delay, 10, spawn_chance , 10}, + { "Yellow Dandelion", "dandelion_yellow", spawn_delay, 10, spawn_chance*2 , 10}, + { "White Dandelion", "dandelion_white", spawn_delay, 10, spawn_chance*2 , 10}, + { "Blue Geranium", "geranium", spawn_delay, 10, spawn_chance , 10}, + { "Viola", "viola", spawn_delay, 10, spawn_chance , 10}, + { "Cotton Plant", "cotton", spawn_delay, 10, spawn_chance*2 , 10}, +} + +local grasses_list = { + {"junglegrass:shortest","junglegrass:short" }, + {"junglegrass:short" ,"junglegrass:medium" }, + {"junglegrass:medium" ,"default:junglegrass" }, + {"default:junglegrass" , nil} +} + +local verticals_list = { + "default:dirt", + "default:dirt_with_grass", + "default:stone", + "default:cobble", + "default:mossycobble", + "default:brick", + "default:tree", + "default:jungletree", + "default:coal", + "default:iron" +} + +-- Local functions + +math.randomseed(os.time()) + +local dbg = function(s) + if plantlife_debug then + print("[Plantlife] " .. s) + end +end + +local is_node_loaded = function(node_pos) + n = minetest.env:get_node_or_nil(node_pos) + if (n == nil) or (n.name == "ignore") then + return false + end + return true +end + +-- The spawning ABM + +spawn_on_surfaces = function(sdelay, splant, sradius, schance, ssurface, savoid, seed_diff, lightmin, lightmax, nneighbors, ocount) + if lightmin == nil then lightmin = 0 end + if lightmax == nil then lightmax = LIGHT_MAX end + if nneighbors == nil then nneighbors = ssurface end + if ocount == nil then ocount = 0 end + dbg(sdelay.." "..splant.." "..sradius.." "..schance.." "..ssurface.." "..dump(savoid).." "..lightmin.." "..lightmax.." "..dump(nneighbors).." "..ocount) + minetest.register_abm({ + nodenames = { ssurface }, + interval = sdelay, + chance = schance, + neighbors = nneighbors, + action = function(pos, node, active_object_count, active_object_count_wider) + local p_top = { x = pos.x, y = pos.y + 1, z = pos.z } + local n_top = minetest.env:get_node(p_top) + local perlin = minetest.env:get_perlin(seed_diff, perlin_octaves, perlin_persistence, perlin_scale ) + local noise = perlin:get2d({x=p_top.x, y=p_top.z}) + if ( noise > plantlife_limit ) and (n_top.name == "air") and is_node_loaded(p_top) then + local n_light = minetest.env:get_node_light(p_top, nil) + if (minetest.env:find_node_near(p_top, sradius, savoid) == nil ) + and (n_light >= lightmin) + and (n_light <= lightmax) + and table.getn(minetest.env:find_nodes_in_area({x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, nneighbors)) > ocount + then + local walldir = plant_valid_wall(p_top) + if splant == "poisonivy:seedling" and walldir ~= nil then + dbg("Spawn: poisonivy:climbing at "..dump(p_top).." on "..ssurface) + minetest.env:add_node(p_top, { name = "poisonivy:climbing", param2 = walldir }) + else + dbg("Spawn: "..splant.." at "..dump(p_top).." on "..ssurface) + minetest.env:add_node(p_top, { name = splant }) + end + end + end + end + }) +end + +-- The growing ABM + +grow_plants = function(gdelay, gchance, gplant, gresult, dry_early_node, dont_grow_nodes) + minetest.register_abm({ + nodenames = { gplant }, + interval = gdelay, + chance = gchance, + action = function(pos, node, active_object_count, active_object_count_wider) + local p_top = {x=pos.x, y=pos.y+1, z=pos.z} + local p_bot = {x=pos.x, y=pos.y-1, z=pos.z} + local n_top = minetest.env:get_node(p_top) + local n_bot = minetest.env:get_node(p_bot) + + dbg("abm triggered for "..gplant.." on "..n_bot.name.." at "..dump(pos).." -- checking if its in "..dump(dont_grow_nodes)) + if string.find(dump(dont_grow_nodes), n_bot.name) == nil and n_top.name == "air" then + dbg("It wasn't, and it has air above it.") + -- corner case for changing short junglegrass to dry shrub in desert + if (n_bot.name == dry_early_node) and (gplant == "junglegrass:short") then + gresult = "default:dry_shrub" + dbg("Want to change "..gplant.." to "..gresult) + end + + -- corner case for wall-climbing poison ivy + if gplant == "poisonivy:climbing" then + dbg("Want to grow "..gplant) + local walldir=plant_valid_wall(p_top) + if walldir ~= nil then + dbg("Grow: "..gplant.." upwards to ("..dump(p_top)..")") + minetest.env:add_node(p_top, { name = gplant, param2 = walldir }) + end + + elseif gresult ~= nil then + dbg("Grow: "..gplant.." -> "..gresult.." at ("..dump(pos)..")") + minetest.env:add_node(pos, { name = gresult }) + else + dbg("Die: "..gplant.." at ("..dump(pos)..")") + minetest.env:remove_node(pos) + end + end + end + }) +end + +-- function to decide if a node has a wall that's in verticals_list{} +-- returns wall direction of valid node, or nil if invalid. + +plant_valid_wall = function(wallpos) + local walldir = nil + local verts = dump(verticals_list) + + local testpos = { x = wallpos.x-1, y = wallpos.y, z = wallpos.z } + if string.find(verts, minetest.env:get_node(testpos).name) ~= nil then walldir=3 end + + local testpos = { x = wallpos.x+1, y = wallpos.y, z = wallpos.z } + if string.find(verts, minetest.env:get_node(testpos).name) ~= nil then walldir=2 end + + local testpos = { x = wallpos.x , y = wallpos.y, z = wallpos.z-1 } + if string.find(verts, minetest.env:get_node(testpos).name) ~= nil then walldir=5 end + + local testpos = { x = wallpos.x , y = wallpos.y, z = wallpos.z+1 } + if string.find(verts, minetest.env:get_node(testpos).name) ~= nil then walldir=4 end + + return walldir +end + +-- ########################################################################### +-- Flowers section + +if enable_flowers then + loadstr = loadstr.." flowers" + for i in ipairs(flowers_list) do + local flowerdesc = flowers_list[i][1] + local flower = flowers_list[i][2] + local delay = flowers_list[i][3] + local radius = flowers_list[i][4] + local chance = flowers_list[i][5] + + minetest.register_node(":flowers:flower_"..flower, { + description = flowerdesc, + drawtype = "plantlike", + tiles = { "flower_"..flower..".png" }, + inventory_image = "flower_"..flower..".png", + wield_image = "flower_"..flower..".png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + groups = { snappy = 3,flammable=2, flower=1 }, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -0.15, -0.5, -0.15, 0.15, 0.2, 0.15 }, + }, + }) + + minetest.register_node(":flowers:flower_"..flower.."_pot", { + description = flowerdesc.." in a pot", + drawtype = "plantlike", + tiles = { "flower_"..flower.."_pot.png" }, + inventory_image = "flower_"..flower.."_pot.png", + wield_image = "flower_"..flower.."_pot.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + groups = { snappy = 3,flammable=2 }, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -0.25, -0.5, -0.25, 0.25, 0.5, 0.25 }, + }, + }) + + minetest.register_craft( { + type = "shapeless", + output = "flowers:flower_"..flower.."_pot", + recipe = { + "flowers:flower_pot", + "flowers:flower_"..flower + } + }) + + spawn_on_surfaces(delay, "flowers:flower_"..flower, radius, chance, "default:dirt_with_grass", {"group:flower"}, flowers_seed_diff) + end + + minetest.register_node(":flowers:flower_waterlily", { + description = "Waterlily", + drawtype = "raillike", + tiles = { "flower_waterlily.png" }, + inventory_image = "flower_waterlily.png", + wield_image = "flower_waterlily.png", + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "wallmounted", + walkable = false, + groups = { snappy = 3,flammable=2,flower=1 }, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -0.4, -0.5, -0.4, 0.4, -0.45, 0.4 }, + }, + }) + + minetest.register_node(":flowers:flower_seaweed", { + description = "Seaweed", + drawtype = "signlike", + tiles = { "flower_seaweed.png" }, + inventory_image = "flower_seaweed.png", + wield_image = "flower_seaweed.png", + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "wallmounted", + walkable = false, + groups = { snappy = 3,flammable=2,flower=1 }, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, -0.4, 0.5 }, + }, + }) + + spawn_on_surfaces(spawn_delay/2, "flowers:flower_waterlily", 15 , spawn_chance*3, "default:water_source" , {"group:flower"}, flowers_seed_diff, 10) + spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:water_source" , {"group:flower"}, flowers_seed_diff, 4, 10, {"default:dirt_with_grass"}, 0) + spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:dirt_with_grass", {"group:flower"}, flowers_seed_diff, 4, 10, {"default:water_source"} , 1) + spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:stone" , {"group:flower"}, flowers_seed_diff, 4, 10, {"default:water_source"} , 6) + + + minetest.register_craftitem(":flowers:flower_pot", { + description = "Flower Pot", + inventory_image = "flower_pot.png", + }) + + minetest.register_craft( { + output = "flowers:flower_pot", + recipe = { + { "default:clay_brick", "", "default:clay_brick" }, + { "", "default:clay_brick", "" } + }, + }) + + minetest.register_craftitem(":flowers:cotton", { + description = "Cotton", + image = "cotton.png", + }) + + minetest.register_craft({ + output = "flowers:cotton 3", + recipe ={ + {"flowers:flower_cotton"}, + } + }) + +end + +-- ########################################################################### +-- Jungle Grass section + +if enable_junglegrass then + loadstr = loadstr.." junglegrass" + + minetest.register_node(':junglegrass:medium', { + description = "Jungle Grass (medium height)", + drawtype = 'plantlike', + tile_images = { 'junglegrass_medium.png' }, + inventory_image = 'junglegrass_medium.png', + wield_image = 'junglegrass_medium.png', + sunlight_propagates = true, + paramtype = 'light', + walkable = false, + groups = { snappy = 3, flammable=2, junglegrass=1 }, + sounds = default.node_sound_leaves_defaults(), + drop = 'default:junglegrass', + + selection_box = { + type = "fixed", + fixed = {-0.4, -0.5, -0.4, 0.4, 0.5, 0.4}, + }, + }) + + minetest.register_node(':junglegrass:short', { + description = "Jungle Grass (short)", + drawtype = 'plantlike', + tile_images = { 'junglegrass_short.png' }, + inventory_image = 'junglegrass_short.png', + wield_image = 'junglegrass_short.png', + sunlight_propagates = true, + paramtype = 'light', + walkable = false, + groups = { snappy = 3, flammable=2, junglegrass=1 }, + sounds = default.node_sound_leaves_defaults(), + drop = 'default:junglegrass', + selection_box = { + type = "fixed", + fixed = {-0.4, -0.5, -0.4, 0.4, 0.3, 0.4}, + }, + }) + + minetest.register_node(':junglegrass:shortest', { + description = "Jungle Grass (very short)", + drawtype = 'plantlike', + tile_images = { 'junglegrass_shortest.png' }, + inventory_image = 'junglegrass_shortest.png', + wield_image = 'junglegrass_shortest.png', + sunlight_propagates = true, + paramtype = 'light', + walkable = false, + groups = { snappy = 3, flammable=2, junglegrass=1 }, + sounds = default.node_sound_leaves_defaults(), + drop = 'default:junglegrass', + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.3}, + }, + }) + + spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance/50, "default:dirt_with_grass", {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) + spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance/50, "default:sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) + spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance/10, "default:desert_sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) + spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance/10, "default:desert_sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) + + for i in ipairs(grasses_list) do + grow_plants(grow_delay, grow_chance/2, grasses_list[i][1], grasses_list[i][2], "default:desert_sand", {"default:cactus", "default:papyrus"}) + end +end + +-- ########################################################################### +-- Poison Ivy section + +if enable_poisonivy then + loadstr = loadstr.." poisonivy" + + minetest.register_node(':poisonivy:seedling', { + description = "Poison ivy (seedling)", + drawtype = 'plantlike', + tile_images = { 'poisonivy_seedling.png' }, + inventory_image = 'poisonivy_seedling.png', + wield_image = 'poisonivy_seedling.png', + sunlight_propagates = true, + paramtype = 'light', + walkable = false, + groups = { snappy = 3, poisonivy=1 }, + sounds = default.node_sound_leaves_defaults(), + }) + + minetest.register_node(':poisonivy:sproutling', { + description = "Poison ivy (sproutling)", + drawtype = 'plantlike', + tile_images = { 'poisonivy_sproutling.png' }, + inventory_image = 'poisonivy_sproutling.png', + wield_image = 'poisonivy_sproutling.png', + sunlight_propagates = true, + paramtype = 'light', + walkable = false, + groups = { snappy = 3, poisonivy=1 }, + sounds = default.node_sound_leaves_defaults(), + }) + + minetest.register_node(':poisonivy:climbing', { + description = "Poison ivy (climbing plant)", + drawtype = 'signlike', + tile_images = { 'poisonivy_climbing.png' }, + inventory_image = 'poisonivy_climbing.png', + wield_image = 'poisonivy_climbing.png', + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = 'wallmounted', + walkable = false, + groups = { snappy = 3, poisonivy=1 }, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "wallmounted", + --wall_side = = + }, + }) + + spawn_on_surfaces(spawn_delay, "poisonivy:seedling", 10 , spawn_chance/10, "default:dirt_with_grass", {"group:poisonivy","group:flower"}, poisonivy_seed_diff, 7) + grow_plants(spawn_delay, grow_chance, "poisonivy:seedling", "poisonivy:sproutling") + grow_plants(spawn_delay, grow_chance*2, "poisonivy:climbing") +end + +print(loadstr..")") diff --git a/plants/init.lua~ b/plants/init.lua~ new file mode 100644 index 0000000..5a9431c --- /dev/null +++ b/plants/init.lua~ @@ -0,0 +1,448 @@ +-- Plantlife mod by Vanessa Ezekowitz +-- 2012-11-29 +-- +-- This mod combines all of the functionality from poison ivy, +-- flowers, and jungle grass. If you have any of these, you no +-- longer need them. +-- +-- License: +-- CC-BY-SA for most textures, except flowers +-- WTFPL for the flowers textures +-- WTFPL for all code and everything else + + +-- Edit these first few variables to turn the various parts on/off +-- or to tweak the overall settings. + +local enable_flowers = true +local enable_junglegrass = true +local enable_poisonivy = true + +local plantlife_debug = true + +local plantlife_seed_diff = 123 +local perlin_octaves = 3 +local perlin_persistence = 0.2 +local perlin_scale = 25 + +local plantlife_limit = 0.6 -- lower = more abundant + +local spawn_delay = 20 -- 2000 +local spawn_chance = 2 -- 100 +local grow_delay = 10 -- 1000 +local grow_chance = 2 -- 10 + +-- Stuff from here on down shouldn't need to be edited. + +local loadstr = "[Plantlife] Loaded (enabled" + +local flowers_seed_diff = plantlife_seed_diff +local junglegrass_seed_diff = plantlife_seed_diff + 10 +local poisonivy_seed_diff = plantlife_seed_diff + 10 + +local flowers_list = { + { "Rose", "rose", spawn_delay, 10, spawn_chance , 10}, + { "Tulip", "tulip", spawn_delay, 10, spawn_chance , 10}, + { "Yellow Dandelion", "dandelion_yellow", spawn_delay, 10, spawn_chance*2 , 10}, + { "White Dandelion", "dandelion_white", spawn_delay, 10, spawn_chance*2 , 10}, + { "Blue Geranium", "geranium", spawn_delay, 10, spawn_chance , 10}, + { "Viola", "viola", spawn_delay, 10, spawn_chance , 10}, + { "Cotton Plant", "cotton", spawn_delay, 10, spawn_chance*2 , 10}, +} + +local grasses_list = { + {"junglegrass:shortest","junglegrass:short" }, + {"junglegrass:short" ,"junglegrass:medium" }, + {"junglegrass:medium" ,"default:junglegrass" }, + {"default:junglegrass" , nil} +} + +local verticals_list = { + "default:dirt", + "default:dirt_with_grass", + "default:stone", + "default:cobble", + "default:mossycobble", + "default:brick", + "default:tree", + "default:jungletree", + "default:coal", + "default:iron" +} + +-- Local functions + +math.randomseed(os.time()) + +local dbg = function(s) + if plantlife_debug then + print("[Plantlife] " .. s) + end +end + +local is_node_loaded = function(node_pos) + n = minetest.env:get_node_or_nil(node_pos) + if (n == nil) or (n.name == "ignore") then + return false + end + return true +end + +-- The spawning ABM + +spawn_on_surfaces = function(sdelay, splant, sradius, schance, ssurface, savoid, seed_diff, lightmin, lightmax, nneighbors, ocount) + if lightmin == nil then lightmin = 0 end + if lightmax == nil then lightmax = LIGHT_MAX end + if nneighbors == nil then nneighbors = ssurface end + if ocount == nil then ocount = 0 end + dbg(sdelay.." "..splant.." "..sradius.." "..schance.." "..ssurface.." "..dump(savoid).." "..lightmin.." "..lightmax.." "..dump(nneighbors).." "..ocount) + minetest.register_abm({ + nodenames = { ssurface }, + interval = sdelay, + chance = schance, + neighbors = nneighbors, + action = function(pos, node, active_object_count, active_object_count_wider) + local p_top = { x = pos.x, y = pos.y + 1, z = pos.z } + local n_top = minetest.env:get_node(p_top) + local perlin = minetest.env:get_perlin(seed_diff, perlin_octaves, perlin_persistence, perlin_scale ) + local noise = perlin:get2d({x=p_top.x, y=p_top.z}) + if ( noise > plantlife_limit ) and (n_top.name == "air") and is_node_loaded(p_top) then + local n_light = minetest.env:get_node_light(p_top, nil) + if (minetest.env:find_node_near(p_top, sradius, savoid) == nil ) +-- and (n_light >= lightmin) +-- and (n_light <= lightmax) + and table.getn(minetest.env:find_nodes_in_area({x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, nneighbors)) > ocount + then + local walldir = plant_valid_wall(p_top) + if splant == "poisonivy:seedling" and walldir ~= nil then + dbg("Spawn: poisonivy:climbing at "..dump(p_top).." on "..ssurface) + minetest.env:add_node(p_top, { name = "poisonivy:climbing", param2 = walldir }) + else + dbg("Spawn: "..splant.." at "..dump(p_top).." on "..ssurface) + minetest.env:add_node(p_top, { name = splant }) + end + end + end + end + }) +end + +-- The growing ABM + +grow_plants = function(gdelay, gchance, gplant, gresult, dry_early_node, dont_grow_nodes) + minetest.register_abm({ + nodenames = { gplant }, + interval = gdelay, + chance = gchance, + action = function(pos, node, active_object_count, active_object_count_wider) + local p_top = {x=pos.x, y=pos.y+1, z=pos.z} + local p_bot = {x=pos.x, y=pos.y-1, z=pos.z} + local n_top = minetest.env:get_node(p_top) + local n_bot = minetest.env:get_node(p_bot) + + dbg("abm triggered for "..gplant.." on "..n_bot.name.." at "..dump(pos).." -- checking if its in "..dump(dont_grow_nodes)) + if string.find(dump(dont_grow_nodes), n_bot.name) == nil and n_top.name == "air" then + dbg("It wasn't, and it has air above it.") + -- corner case for changing short junglegrass to dry shrub + if (n_bot.name == dry_early_node) and (gplant == "junglegrass:short") then + gresult = "default:dry_shrub" + dbg("Want to change "..gplant.." to "..gresult) + end + + -- corner case for wall-climbing poison ivy + if gplant == "poisonivy:climbing" then + dbg("Want to grow "..gplant) + local walldir=plant_valid_wall(p_top) + if walldir ~= nil then + dbg("Grow: "..gplant.." upwards to ("..dump(p_top)..")") + minetest.env:add_node(p_top, { name = gplant, param2 = walldir }) + end + + elseif gresult ~= nil then + dbg("Grow: "..gplant.." -> "..gresult.." at ("..dump(pos)..")") + minetest.env:add_node(pos, { name = gresult }) + else + dbg("Die: "..gplant.." at ("..dump(pos)..")") + minetest.env:remove_node(pos) + end + end + end + }) +end + +-- function to decide if a node has a wall that's in verticals_list{} +-- returns wall direction of valid node, or nil if invalid. + +plant_valid_wall = function(wallpos) + local walldir = nil + local verts = dump(verticals_list) + + local testpos = { x = wallpos.x-1, y = wallpos.y, z = wallpos.z } + if string.find(verts, minetest.env:get_node(testpos).name) ~= nil then walldir=3 end + + local testpos = { x = wallpos.x+1, y = wallpos.y, z = wallpos.z } + if string.find(verts, minetest.env:get_node(testpos).name) ~= nil then walldir=2 end + + local testpos = { x = wallpos.x , y = wallpos.y, z = wallpos.z-1 } + if string.find(verts, minetest.env:get_node(testpos).name) ~= nil then walldir=5 end + + local testpos = { x = wallpos.x , y = wallpos.y, z = wallpos.z+1 } + if string.find(verts, minetest.env:get_node(testpos).name) ~= nil then walldir=4 end + + return walldir +end + +-- ########################################################################### +-- Flowers section + +if enable_flowers then + loadstr = loadstr.." flowers" + for i in ipairs(flowers_list) do + local flowerdesc = flowers_list[i][1] + local flower = flowers_list[i][2] + local delay = flowers_list[i][3] + local radius = flowers_list[i][4] + local chance = flowers_list[i][5] + + minetest.register_node(":flowers:flower_"..flower, { + description = flowerdesc, + drawtype = "plantlike", + tiles = { "flower_"..flower..".png" }, + inventory_image = "flower_"..flower..".png", + wield_image = "flower_"..flower..".png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + groups = { snappy = 3,flammable=2, flower=1 }, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -0.15, -0.5, -0.15, 0.15, 0.2, 0.15 }, + }, + }) + + minetest.register_node(":flowers:flower_"..flower.."_pot", { + description = flowerdesc.." in a pot", + drawtype = "plantlike", + tiles = { "flower_"..flower.."_pot.png" }, + inventory_image = "flower_"..flower.."_pot.png", + wield_image = "flower_"..flower.."_pot.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + groups = { snappy = 3,flammable=2 }, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -0.25, -0.5, -0.25, 0.25, 0.5, 0.25 }, + }, + }) + + minetest.register_craft( { + type = "shapeless", + output = "flowers:flower_"..flower.."_pot", + recipe = { + "flowers:flower_pot", + "flowers:flower_"..flower + } + }) + + spawn_on_surfaces(delay, "flowers:flower_"..flower, radius, chance, "default:dirt_with_grass", {"group:flower"}, flowers_seed_diff) + end + + minetest.register_node(":flowers:flower_waterlily", { + description = "Waterlily", + drawtype = "raillike", + tiles = { "flower_waterlily.png" }, + inventory_image = "flower_waterlily.png", + wield_image = "flower_waterlily.png", + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "wallmounted", + walkable = false, + groups = { snappy = 3,flammable=2,flower=1 }, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -0.4, -0.5, -0.4, 0.4, -0.45, 0.4 }, + }, + }) + + minetest.register_node(":flowers:flower_seaweed", { + description = "Seaweed", + drawtype = "signlike", + tiles = { "flower_seaweed.png" }, + inventory_image = "flower_seaweed.png", + wield_image = "flower_seaweed.png", + sunlight_propagates = true, + paramtype = "light", + paramtype2 = "wallmounted", + walkable = false, + groups = { snappy = 3,flammable=2,flower=1 }, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, -0.4, 0.5 }, + }, + }) + + spawn_on_surfaces(spawn_delay/2, "flowers:flower_waterlily", 15 , spawn_chance*3, "default:water_source" , {"group:flower"}, flowers_seed_diff, 10) + spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:water_source" , {"group:flower"}, flowers_seed_diff, 4, 10, {"default:dirt_with_grass"}, 0) + spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:dirt_with_grass", {"group:flower"}, flowers_seed_diff, 4, 10, {"default:water_source"} , 1) + spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:stone" , {"group:flower"}, flowers_seed_diff, 4, 10, {"default:water_source"} , 6) + + + minetest.register_craftitem(":flowers:flower_pot", { + description = "Flower Pot", + inventory_image = "flower_pot.png", + }) + + minetest.register_craft( { + output = "flowers:flower_pot", + recipe = { + { "default:clay_brick", "", "default:clay_brick" }, + { "", "default:clay_brick", "" } + }, + }) + + minetest.register_craftitem(":flowers:cotton", { + description = "Cotton", + image = "cotton.png", + }) + + minetest.register_craft({ + output = "flowers:cotton 3", + recipe ={ + {"flowers:flower_cotton"}, + } + }) + +end + +-- ########################################################################### +-- Jungle Grass section + +if enable_junglegrass then + loadstr = loadstr.." junglegrass" + + minetest.register_node(':junglegrass:medium', { + description = "Jungle Grass (medium height)", + drawtype = 'plantlike', + tile_images = { 'junglegrass_medium.png' }, + inventory_image = 'junglegrass_medium.png', + wield_image = 'junglegrass_medium.png', + sunlight_propagates = true, + paramtype = 'light', + walkable = false, + groups = { snappy = 3, flammable=2, junglegrass=1 }, + sounds = default.node_sound_leaves_defaults(), + drop = 'default:junglegrass', + + selection_box = { + type = "fixed", + fixed = {-0.4, -0.5, -0.4, 0.4, 0.5, 0.4}, + }, + }) + + minetest.register_node(':junglegrass:short', { + description = "Jungle Grass (short)", + drawtype = 'plantlike', + tile_images = { 'junglegrass_short.png' }, + inventory_image = 'junglegrass_short.png', + wield_image = 'junglegrass_short.png', + sunlight_propagates = true, + paramtype = 'light', + walkable = false, + groups = { snappy = 3, flammable=2, junglegrass=1 }, + sounds = default.node_sound_leaves_defaults(), + drop = 'default:junglegrass', + selection_box = { + type = "fixed", + fixed = {-0.4, -0.5, -0.4, 0.4, 0.3, 0.4}, + }, + }) + + minetest.register_node(':junglegrass:shortest', { + description = "Jungle Grass (very short)", + drawtype = 'plantlike', + tile_images = { 'junglegrass_shortest.png' }, + inventory_image = 'junglegrass_shortest.png', + wield_image = 'junglegrass_shortest.png', + sunlight_propagates = true, + paramtype = 'light', + walkable = false, + groups = { snappy = 3, flammable=2, junglegrass=1 }, + sounds = default.node_sound_leaves_defaults(), + drop = 'default:junglegrass', + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.3}, + }, + }) + + spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance/50, "default:dirt_with_grass", {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) + spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance/50, "default:sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) + spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance/10, "default:desert_sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) + spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance/10, "default:desert_sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) + + for i in ipairs(grasses_list) do + grow_plants(grow_delay, grow_chance/2, grasses_list[i][1], grasses_list[i][2], "default:desert_sand", {"default:cactus", "default:papyrus"}) + end +end + +-- ########################################################################### +-- Poison Ivy section + +if enable_poisonivy then + loadstr = loadstr.." poisonivy" + + minetest.register_node(':poisonivy:seedling', { + description = "Poison ivy (seedling)", + drawtype = 'plantlike', + tile_images = { 'poisonivy_seedling.png' }, + inventory_image = 'poisonivy_seedling.png', + wield_image = 'poisonivy_seedling.png', + sunlight_propagates = true, + paramtype = 'light', + walkable = false, + groups = { snappy = 3, poisonivy=1 }, + sounds = default.node_sound_leaves_defaults(), + }) + + minetest.register_node(':poisonivy:sproutling', { + description = "Poison ivy (sproutling)", + drawtype = 'plantlike', + tile_images = { 'poisonivy_sproutling.png' }, + inventory_image = 'poisonivy_sproutling.png', + wield_image = 'poisonivy_sproutling.png', + sunlight_propagates = true, + paramtype = 'light', + walkable = false, + groups = { snappy = 3, poisonivy=1 }, + sounds = default.node_sound_leaves_defaults(), + }) + + minetest.register_node(':poisonivy:climbing', { + description = "Poison ivy (climbing plant)", + drawtype = 'signlike', + tile_images = { 'poisonivy_climbing.png' }, + inventory_image = 'poisonivy_climbing.png', + wield_image = 'poisonivy_climbing.png', + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = 'wallmounted', + walkable = false, + groups = { snappy = 3, poisonivy=1 }, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "wallmounted", + --wall_side = = + }, + }) + + spawn_on_surfaces(spawn_delay, "poisonivy:seedling", 10 , spawn_chance/10, "default:dirt_with_grass", {"group:poisonivy","group:flower"}, poisonivy_seed_diff, 7) + grow_plants(spawn_delay, grow_chance, "poisonivy:seedling", "poisonivy:sproutling") + grow_plants(spawn_delay, grow_chance*2, "poisonivy:climbing") +end + +print(loadstr..")") diff --git a/plants/textures/cotton.png b/plants/textures/cotton.png new file mode 100644 index 0000000..c184db2 Binary files /dev/null and b/plants/textures/cotton.png differ diff --git a/plants/textures/flower_cotton.png b/plants/textures/flower_cotton.png new file mode 100644 index 0000000..7b046dd Binary files /dev/null and b/plants/textures/flower_cotton.png differ diff --git a/plants/textures/flower_cotton_pot.png b/plants/textures/flower_cotton_pot.png new file mode 100644 index 0000000..9432adf Binary files /dev/null and b/plants/textures/flower_cotton_pot.png differ diff --git a/plants/textures/flower_dandelion_white.png b/plants/textures/flower_dandelion_white.png new file mode 100644 index 0000000..b22d6d4 Binary files /dev/null and b/plants/textures/flower_dandelion_white.png differ diff --git a/plants/textures/flower_dandelion_white_pot.png b/plants/textures/flower_dandelion_white_pot.png new file mode 100644 index 0000000..1b48fe6 Binary files /dev/null and b/plants/textures/flower_dandelion_white_pot.png differ diff --git a/plants/textures/flower_dandelion_yellow.png b/plants/textures/flower_dandelion_yellow.png new file mode 100644 index 0000000..500adef Binary files /dev/null and b/plants/textures/flower_dandelion_yellow.png differ diff --git a/plants/textures/flower_dandelion_yellow_pot.png b/plants/textures/flower_dandelion_yellow_pot.png new file mode 100644 index 0000000..42a0cd7 Binary files /dev/null and b/plants/textures/flower_dandelion_yellow_pot.png differ diff --git a/plants/textures/flower_geranium.png b/plants/textures/flower_geranium.png new file mode 100644 index 0000000..5325982 Binary files /dev/null and b/plants/textures/flower_geranium.png differ diff --git a/plants/textures/flower_geranium_pot.png b/plants/textures/flower_geranium_pot.png new file mode 100644 index 0000000..f7932f4 Binary files /dev/null and b/plants/textures/flower_geranium_pot.png differ diff --git a/plants/textures/flower_pot.png b/plants/textures/flower_pot.png new file mode 100644 index 0000000..1c16464 Binary files /dev/null and b/plants/textures/flower_pot.png differ diff --git a/plants/textures/flower_rose.png b/plants/textures/flower_rose.png new file mode 100644 index 0000000..4047d3f Binary files /dev/null and b/plants/textures/flower_rose.png differ diff --git a/plants/textures/flower_rose_pot.png b/plants/textures/flower_rose_pot.png new file mode 100644 index 0000000..6723aad Binary files /dev/null and b/plants/textures/flower_rose_pot.png differ diff --git a/plants/textures/flower_seaweed.png b/plants/textures/flower_seaweed.png new file mode 100644 index 0000000..5d34ec9 Binary files /dev/null and b/plants/textures/flower_seaweed.png differ diff --git a/plants/textures/flower_tulip.png b/plants/textures/flower_tulip.png new file mode 100644 index 0000000..5686997 Binary files /dev/null and b/plants/textures/flower_tulip.png differ diff --git a/plants/textures/flower_tulip_pot.png b/plants/textures/flower_tulip_pot.png new file mode 100644 index 0000000..6ee4c8a Binary files /dev/null and b/plants/textures/flower_tulip_pot.png differ diff --git a/plants/textures/flower_viola.png b/plants/textures/flower_viola.png new file mode 100644 index 0000000..21e17bd Binary files /dev/null and b/plants/textures/flower_viola.png differ diff --git a/plants/textures/flower_viola_pot.png b/plants/textures/flower_viola_pot.png new file mode 100644 index 0000000..db02084 Binary files /dev/null and b/plants/textures/flower_viola_pot.png differ diff --git a/plants/textures/flower_waterlily.png b/plants/textures/flower_waterlily.png new file mode 100644 index 0000000..0235d84 Binary files /dev/null and b/plants/textures/flower_waterlily.png differ diff --git a/plants/textures/junglegrass_medium.png b/plants/textures/junglegrass_medium.png new file mode 100644 index 0000000..040452a Binary files /dev/null and b/plants/textures/junglegrass_medium.png differ diff --git a/plants/textures/junglegrass_short.png b/plants/textures/junglegrass_short.png new file mode 100644 index 0000000..5d934e6 Binary files /dev/null and b/plants/textures/junglegrass_short.png differ diff --git a/plants/textures/junglegrass_shortest.png b/plants/textures/junglegrass_shortest.png new file mode 100644 index 0000000..5f94d38 Binary files /dev/null and b/plants/textures/junglegrass_shortest.png differ diff --git a/plants/textures/poisonivy_climbing.png b/plants/textures/poisonivy_climbing.png new file mode 100644 index 0000000..52077e4 Binary files /dev/null and b/plants/textures/poisonivy_climbing.png differ diff --git a/plants/textures/poisonivy_seedling.png b/plants/textures/poisonivy_seedling.png new file mode 100644 index 0000000..e9dcfda Binary files /dev/null and b/plants/textures/poisonivy_seedling.png differ diff --git a/plants/textures/poisonivy_sproutling.png b/plants/textures/poisonivy_sproutling.png new file mode 100644 index 0000000..c739257 Binary files /dev/null and b/plants/textures/poisonivy_sproutling.png differ diff --git a/poinsonivy/depends.txt b/poinsonivy/depends.txt new file mode 100644 index 0000000..e69de29 diff --git a/poinsonivy/init.lua b/poinsonivy/init.lua new file mode 100644 index 0000000..e69de29