From fce9f492c7f75bd56d9395bc92bb153c610799a4 Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Thu, 29 Nov 2012 22:59:45 -0500 Subject: [PATCH] initial commit --- README | 84 ++++ README~ | 60 +++ copyright.txt | 10 + flowers-changelog.txt | 24 + flowers/depends.txt | 0 flowers/init.lua | 0 junglegrass-changelog.txt | 24 + junglegrass/depends.txt | 0 junglegrass/init.lua | 0 license.txt | 3 + modpack.txt | 0 plants/depends.txt | 1 + plants/init.lua | 448 ++++++++++++++++++ plants/init.lua~ | 448 ++++++++++++++++++ plants/textures/cotton.png | Bin 0 -> 680 bytes plants/textures/flower_cotton.png | Bin 0 -> 315 bytes plants/textures/flower_cotton_pot.png | Bin 0 -> 498 bytes plants/textures/flower_dandelion_white.png | Bin 0 -> 169 bytes .../textures/flower_dandelion_white_pot.png | Bin 0 -> 464 bytes plants/textures/flower_dandelion_yellow.png | Bin 0 -> 166 bytes .../textures/flower_dandelion_yellow_pot.png | Bin 0 -> 462 bytes plants/textures/flower_geranium.png | Bin 0 -> 361 bytes plants/textures/flower_geranium_pot.png | Bin 0 -> 520 bytes plants/textures/flower_pot.png | Bin 0 -> 405 bytes plants/textures/flower_rose.png | Bin 0 -> 171 bytes plants/textures/flower_rose_pot.png | Bin 0 -> 479 bytes plants/textures/flower_seaweed.png | Bin 0 -> 416 bytes plants/textures/flower_tulip.png | Bin 0 -> 159 bytes plants/textures/flower_tulip_pot.png | Bin 0 -> 470 bytes plants/textures/flower_viola.png | Bin 0 -> 140 bytes plants/textures/flower_viola_pot.png | Bin 0 -> 465 bytes plants/textures/flower_waterlily.png | Bin 0 -> 221 bytes plants/textures/junglegrass_medium.png | Bin 0 -> 537 bytes plants/textures/junglegrass_short.png | Bin 0 -> 370 bytes plants/textures/junglegrass_shortest.png | Bin 0 -> 325 bytes plants/textures/poisonivy_climbing.png | Bin 0 -> 456 bytes plants/textures/poisonivy_seedling.png | Bin 0 -> 270 bytes plants/textures/poisonivy_sproutling.png | Bin 0 -> 426 bytes poinsonivy/depends.txt | 0 poinsonivy/init.lua | 0 40 files changed, 1102 insertions(+) create mode 100644 README create mode 100644 README~ create mode 100644 copyright.txt create mode 100644 flowers-changelog.txt create mode 100644 flowers/depends.txt create mode 100644 flowers/init.lua create mode 100644 junglegrass-changelog.txt create mode 100644 junglegrass/depends.txt create mode 100644 junglegrass/init.lua create mode 100644 license.txt create mode 100644 modpack.txt create mode 100644 plants/depends.txt create mode 100644 plants/init.lua create mode 100644 plants/init.lua~ create mode 100644 plants/textures/cotton.png create mode 100644 plants/textures/flower_cotton.png create mode 100644 plants/textures/flower_cotton_pot.png create mode 100644 plants/textures/flower_dandelion_white.png create mode 100644 plants/textures/flower_dandelion_white_pot.png create mode 100644 plants/textures/flower_dandelion_yellow.png create mode 100644 plants/textures/flower_dandelion_yellow_pot.png create mode 100644 plants/textures/flower_geranium.png create mode 100644 plants/textures/flower_geranium_pot.png create mode 100644 plants/textures/flower_pot.png create mode 100644 plants/textures/flower_rose.png create mode 100644 plants/textures/flower_rose_pot.png create mode 100644 plants/textures/flower_seaweed.png create mode 100644 plants/textures/flower_tulip.png create mode 100644 plants/textures/flower_tulip_pot.png create mode 100644 plants/textures/flower_viola.png create mode 100644 plants/textures/flower_viola_pot.png create mode 100644 plants/textures/flower_waterlily.png create mode 100644 plants/textures/junglegrass_medium.png create mode 100644 plants/textures/junglegrass_short.png create mode 100644 plants/textures/junglegrass_shortest.png create mode 100644 plants/textures/poisonivy_climbing.png create mode 100644 plants/textures/poisonivy_seedling.png create mode 100644 plants/textures/poisonivy_sproutling.png create mode 100644 poinsonivy/depends.txt create mode 100644 poinsonivy/init.lua 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 0000000000000000000000000000000000000000..c184db25a22b83fddef424ab990e65b24903c44f GIT binary patch literal 680 zcmV;Z0$2TsP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipt` z3K<$u{=q>200JmUL_t(I%dL~KYZO5k#ecK8TeIC5=Yo32+CvecJvG zyaql3Pl0Pnsm^(VO=HZn(P-3)uYOk)!}d`@;sj_^?kn{;HQZ5#tGQpyh5-DY&h(@D96h$cYdp)eR?C zYPCjZ2z=k)%CgL{)?%$iYdr^*YciRzva*7;cKiGyeGozfgTa6(ifFgnxUNf*Bp74n z1gE|jA;b@@^<%BInwvNn3_dxIb3+JG6+&RGMF_!oJVr{1F@_)r=yWQL70(Y)*K0-AbW|YuPgg)9v)5u;e4ftaG=m`PZ!4!i_>o> zZRBk>5OAHZERwe46wkz_CN=IQXEa#Z=uU8HdbEPt4Wl zf7$>4ul0||-vbt=T{aO@=u38SVU$SLIbgt};<-qSm0{JYO;OqZ^KOeZnE2ke2<*t| z5p=&4^;_!DyXHo@1+T5%xjuAl_?*Rd`RCp9sgaXXB^%DC6n7N=E^d6lp_eKcxc#{3 zgBNBGj+j55@;>*(-B(h}pX{p(dcOGAt4n;-GcJDOX3g|*US9De6X*>FPgg&ebxsLQ E0C%Z(`~Uy| literal 0 HcmV?d00001 diff --git a/plants/textures/flower_cotton_pot.png b/plants/textures/flower_cotton_pot.png new file mode 100644 index 0000000000000000000000000000000000000000..9432adf8ffcab9b8adeb6ce5d5308f2350d0ba45 GIT binary patch literal 498 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)9v)63ga5_e%Yj0&nIRD+&iT2y zsd*(pE(3#eQEFmIYKlU6W=V#EyQgnJie4%^&^k{~7sn8b)4h}SdNDhSwC=Z#!}xg8gFT7w&KokxpKT87 z-#y~_tn$~7CY|4&rwq@%|6j=PVaMGIzg1j?yd8V5{#ZIiI)qb0_OZI=C%N@rQCkoE jn|s1&f{f$Zs`7n|kE*AYe|w<39u(T1u6{1-oD!M<`)A2a literal 0 HcmV?d00001 diff --git a/plants/textures/flower_dandelion_white.png b/plants/textures/flower_dandelion_white.png new file mode 100644 index 0000000000000000000000000000000000000000..b22d6d4644b7cc8cc1ff653d9c58d163d2ec79db GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|l097o(u`H(92`!1w&QKh4$2!MF6?CM7Z6oM629UqUE1!^C9@uhz7< R#R08j@O1TaS?83{1OP(iJX8Px literal 0 HcmV?d00001 diff --git a/plants/textures/flower_dandelion_white_pot.png b/plants/textures/flower_dandelion_white_pot.png new file mode 100644 index 0000000000000000000000000000000000000000..1b48fe6e963cd7bfa2fd241aa9ed243bf0a89e6b GIT binary patch literal 464 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!6#=yXs@#Xw?AcrO0(btiIVPik{pF~z5pDoGT z-GxB|1i2*>B!D8E1s;*b3=G`DAk4@xYYs?|y~NYkmHjpkn~1*ny)dWgKq1Kz*N775 z{M_8syb=cIqSVBa)D(sC%#sWRcTeAd@J2pypsgC7E{-7%|->(7JzT_0$Jh z*OXdvq_}mr2!t@TaWKXoICbt`*czRqm%=|N*06CqT03%oT<)CgGtvOw1 z)uLA{-*wcy{Mj5yhIQ-oMH+e+f1K~W>sQPgx4jl!=R=b3Ucb9DlXXJM^03XV@!uk2 zBBot=^<+zJ*4ig8Z-+Z95qvkJ_ndWX`hs1tr(fUo@^jziYh@PM$5X#U`mOT*kkE0n6a&>gTe~DWM4f D1XQw; literal 0 HcmV?d00001 diff --git a/plants/textures/flower_dandelion_yellow.png b/plants/textures/flower_dandelion_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..500adef8efb469520f44acb82102945520c3cc29 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|54w#*DsIMh&NDbHKmL;Z^NEG`g2}={2>}+hOr8IlpPHs{ z3a2JIa0sL}+}GLmUxi)C=kjLb{}1lnnDVWA;*tmlvnOZP*hgGtV%VT3^Xlr1|L#D$ O7(8A5T-G@yGywo3={m9i literal 0 HcmV?d00001 diff --git a/plants/textures/flower_dandelion_yellow_pot.png b/plants/textures/flower_dandelion_yellow_pot.png new file mode 100644 index 0000000000000000000000000000000000000000..42a0cd7530a726cd72e217454cbcd92d6a12fba1 GIT binary patch literal 462 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!6#=yXs@#Xw?AcrO0(btiIVPik{pF~z5pDoGT z-GxB|1i2*>B!D8E1s;*b3=G`DAk4@xYYs?|y~NYkmHjpkn~1*tw~$|)Kq1Kz*N775 z{M_8syb=cIqSVBa)D(sC%#sWRcTeAd@J2pypsi}2E{-7&5IS(z<`9th2!^ zjx!kPC0#ZRDEq zMon{3yy=-aJD<<9W_DQJrgPw&Ym?%ZtQF~t<4$%OuE-bJvfp5F#PU~~T^9e+KC4_T z&e+xcwZ`rJeY=HDLBe`_vbOC#@z%|9?e3{d+LpcjzJ0M!PweBT7;b%yjzUWuIgtPq8*yS7L7DY(u zb*5C^iV8c%tl1FYk+9~V#Oc-gUFp};o(S-ZZMK>--;K*Lq37X?g=atdp6+?G;B>L- z>i)idm7sIV@wJ^-cR8|d%iqt@#K1Y{Iscr4{O4k_!{=Lj<^hA1!PC{xWt~$(69AQ6 BwTS=# literal 0 HcmV?d00001 diff --git a/plants/textures/flower_geranium.png b/plants/textures/flower_geranium.png new file mode 100644 index 0000000000000000000000000000000000000000..5325982eac3e749ef71ec3c2e16df67bd5a730e6 GIT binary patch literal 361 zcmV-v0ha!WP)>P|7_OhMV&GyCXHYe9 zC(Z?SfwTY1Xp}HKJhzR(RG**0)=Gq7#==(&U;iIsU}xcA*uN$Pu8#$q0bjppFg&`r zmw}n_FN3h)Zw6lO9}GVj&NKY~Zo%;R|91w0Uii=Oo#EHtZwxE~yBLn1dCySOeVaj6 zBah+F{~rvDj6aAALiT?5MvKF&f4HM&AJnB8g%on!G$ZUD1o#72<5R&D%Xk_V`%Iw{abLex-Q$B zYZP3Kmv^~8=TY!ln8c;Ew@hWBCcV5mEhx{|#MMRe{uV(#;G}&O8@xlz7}4P@Uq0O$ zoWZxxRn-p9Fgf*%!>G-1r$cz~h>6Ru`i4_C=&ee%E=ot3*yHQk?SX7&J$*ANgZg?< zbNOW;VnZIUc$t#EwRRWFGMp2%SenwIIjK(WsQjQiEBUD#_}l01*oUN-17!AMtu?zmIp)1aV?%geQ6U-O||L(0000< KMNUMnLSTZx$>pd3 literal 0 HcmV?d00001 diff --git a/plants/textures/flower_pot.png b/plants/textures/flower_pot.png new file mode 100644 index 0000000000000000000000000000000000000000..1c16464ceb8e86d29deae07c146999df3d557fb0 GIT binary patch literal 405 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!6#=yXs@#Xw?AcrO0(btiIVPik{pF~z5pDoGT z-GxB|1i2*>B!D8E1s;*b3=G`DAk4@xYYs?|y~NYkmHjpkn~0`qY|fIeKq1Kz*N775 z{M_8syb=cIqSVBa)D(sC%#sWRcTeAd@J2pyprW^)E{-7{=f>&5IS;&y(ntm2MY zTR9XrZoF_P$R$9D93i85tXeK7<6< z6u;XmKjq=B*zlGA=PuhOp5|q_Z^NUF_fCBIBiGTjMA&ZLmtQBhmuwHcdbH?ie_H>< z^TyX-UHwxkAd|Ml?%|H_DGd8KwivzNHcPaiZ|C84yjNq_`MgRief9sV!Ma)8dFIom zs46@aXk~fEV|+YWU^DyjZ;Kfc(l;)<`!jP12a|E~`&H-v-Q4?km*c_M-OHvsItZ=w u&yca@Ir}TH>Fj6oPd4sM^IIm$)-dp&^()=HdxI{};|!jzelF{r5}E*4QlKjU literal 0 HcmV?d00001 diff --git a/plants/textures/flower_rose.png b/plants/textures/flower_rose.png new file mode 100644 index 0000000000000000000000000000000000000000..4047d3ff25045e93dbb685eabd382c12df65e308 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|QaxQ9Lo7}w zCrGd|^Gkg6oR^sJB!D8E1s;*b3=G`DAk4@xYYs?|y~NYkmHjpkn}`le;n9FDppayVYeb22 zer|4RUI~M9QEFmIYKlU6W=V#EyQgnJcq5-U&{lI#7sn8b(@Q7Wdow!<9IfBH-OFIs zW)8)T8!sp=^>FAE_`n@;Gc#8^Y+BOG@D1C(8AotLE!oudzsp35xl2OSq}*JrN=UET z@<{kuqx`h{)w>x?92r;S-h6+kckvAI#dkG&AEhta8+CE+&rH?{2i=6Xd=1W5t72Fq z+m{{mRzG{`o7b S7hwntX9iDKKbLh*2~7ZBfV|cK literal 0 HcmV?d00001 diff --git a/plants/textures/flower_seaweed.png b/plants/textures/flower_seaweed.png new file mode 100644 index 0000000000000000000000000000000000000000..5d34ec9da3f1d9ef73244f76990634e598526014 GIT binary patch literal 416 zcmV;R0bl-!P)YN5?qJWrjeaax6WiE?G0&vLauj{ zsNjzWrStU|%d8*)Yfc`NB!@=ygUe%4Non#rMY+5)j35B$2bTdf(?4A5yu}JdLvR>X zwy-0ND*F@CI)i1_4D7tcp)nhL+Qd3a$N3W6K$=G-`OVkQFUYIO-Pq;Oc$zKc9R|z8{kbzjIFg6sxgFB!D8E1s;*b3=G`DAk4@xYYs?|y~NYkmHjpkn}`8ldHR!+Kq1Kz*N775 z{M_8syb=cIqSVBa)D(sC%#sWRcTeAd@J2pypsjkIE{-7+KXMajgFR&gBBS zxdIobbx27$w=6o4k&&Bq`ljiuMVeB-`IV$*|CW|&nk94VmsHFt7G+b=GIaPuXFFRwimTo9G3Xt;2+bF$oBh7nny;R{k^gtyENeSv9(JiJ-lygH`p^qEcox4b|5ZQxm+AE4%=epL zOSyPNwy%D+o8e3Oj!7HSmQP?vp0P8-fa0FN3G6 KpUXO@geCyHj=u>2 literal 0 HcmV?d00001 diff --git a/plants/textures/flower_viola.png b/plants/textures/flower_viola.png new file mode 100644 index 0000000000000000000000000000000000000000..21e17bdedab64d71b333087d8513aecb6c130494 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|+&o9GliBFv_q`eYoB7>)^pUXO@geCxvrY$c3 literal 0 HcmV?d00001 diff --git a/plants/textures/flower_viola_pot.png b/plants/textures/flower_viola_pot.png new file mode 100644 index 0000000000000000000000000000000000000000..db02084e2c9b3f9753c52673e0132f3bc848b123 GIT binary patch literal 465 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!6#=yXs@#Xw?AcrO0(btiIVPik{pF~z5pDoGT z-GxB|1i2*>B!D8E1s;*b3=G`DAk4@xYYs?|y~NYkmHjpkn}~s)59bj^ppayVYeb22 zer|4RUI~M9QEFmIYKlU6W=V#EyQgnJcq5-U&{j=P7sn8b(_1I)^PgSvI-Q$l-n^uS>%X7o%P^do1{wkhbLVU(ro(i)u3B zuJuM__hqa*d%2jwh{36e#f8&FB#zgxv_|zBE5iok@CWzKu$&N3P*A$D|NWy6zaow5 z1um`=`*G1&fiv7%WA5G)0kUiE*C=u@O=u|d$?~^%I$L;K?8lT$V8}9fy85}Sb4q9e E0GSZB6aWAK literal 0 HcmV?d00001 diff --git a/plants/textures/flower_waterlily.png b/plants/textures/flower_waterlily.png new file mode 100644 index 0000000000000000000000000000000000000000..0235d8499dfa133d595d653c2a551137ee8a9dbe GIT binary patch literal 221 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|rhB?LhFF|V zPFP@G@%d0OIyjfp{-(LWL z?dr&Qpi5#yH3|oaqbqBB()oc0x}sfXHR9;XCd;98#wHG%0wQggH|tB=wLnr78qp#q zWmdx(n~J{eTDY8VxQizYt|>oy0FdlYic+zAuw;Mg_;D9c1p=5Jmq=3u*)c zfnhA6ZV6VmO2`EgeT~=Zpe1L2< z%*-49{8`}t-ThP*u`eIo15X#@9z0)7yu(0RvJY~Bp_1UQ29vMfK5Xr){qgT-nn_Dm zRm83W(vnU7<_fNS0}NxIAA!&5m_o!9!o)88{_-hY6~Zm<>N5bKZ91W2SgR z^;?*pyi5Q9>*ZGT1`LNhJdUud&xk2RR;0+w1jo%4d6`%k0HiBtz1#}Yl4A;SI$Y2; zogfX)XMXtRCERO}mONigc)A$(%rt&k6V0BgitM?vBE{3Qvj3oMIx#%sFXn)Pe4Y8Z QT>t<807*qoM6N<$g3$w*xc~qF literal 0 HcmV?d00001 diff --git a/plants/textures/junglegrass_shortest.png b/plants/textures/junglegrass_shortest.png new file mode 100644 index 0000000000000000000000000000000000000000..5f94d3840f5e8686128664b1292d70efd8b1949a GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4$}ele^Fu3V@O6yYrJ zh%9Dc;1&j9Muu5)B!GhKC7!;n?048Xc?`MjrXDf?3SIJaaSX9I{dR&a*P#G`mi@~c zO_~%q0yhdYWlUFFn;^WWsdujU2Zgu;=ZFVdQ&MBb@0KQs&@&Et; literal 0 HcmV?d00001 diff --git a/plants/textures/poisonivy_climbing.png b/plants/textures/poisonivy_climbing.png new file mode 100644 index 0000000000000000000000000000000000000000..52077e44afd14862a3309b347229a8bf90e0cc65 GIT binary patch literal 456 zcmV;(0XP1MP)7>!cgTA12=@>i*|3E$=Lm;EKd_cb1PM!q?ky5(%g;CpRV-5>N}E^dG%4O^qw>bqojWB|a^ z^YyPf*v*XH-%Yp%>Af5hWf5^L)H**fZzAycaMgJJ{Sp9N z-d`Y=0mU*PUALO=8GH`{zK7Lp_v0%H0D!m~7$?e8^MjWE0G2Nwth3kd>S}_*+sEh6Z0000p_??PHLhIP>{XE z)7O>#4lApWkkQZS@xOsWYdu{YLo7}wCrGe5iNR1n&x_a&PN3<+M&Xx(sQ6S5Qv=`<^1Iz=qO}`|}VG}%znNddNUcy$J z0U+;85cqCUr)vPfkV3)dts*&3GniJb(4ZeVWLh=wFlK@8l6*S=4`bFivVKI=s9KbL zyAJLpOVqSKPcvvLS_@X@ZC%Wu5y}G|o=?agwUM5`